Making Noise
The basics of interpolating randomness.
Making noise
The Book of Shaders Chapter 10 shows us how to generate a pseudo-random floating point value based on an input vec2
:
We take the dot product of the input vector with some crazy vec2 (vec2(12.9898,78.233)
for instance), multiply the result by some crazy amount (43758.
etc), take the sin
of that, and then grab only the fractional component (the parts after the decimal), to get a random value in the range $[0,1)$ (in the notation of ranges, the $)$ sign means everything upto but excluding $1$). We call it a pseudo random number because two identical inputs will generate identical outputs.
Now, with this function, let’s take a look at a function in the book of shaders, which is based on work by Morgan McGuire:
Let’s say our input to this function is a vec2
coordinate that has been multiplied by 5. vec2 i = floor(st)
will give us vec2
s composed of integers between 0 and 5, while vec2 i = fract(st)
will give us vec2
s composed of floating point numbers between 0 and 1.
We use i
to calculate the pseudo random number at four fixed points on our grid, and f
to calculate a smooth interpolation between 0 and 1. Finally, we use the smooth interpolation to mix our four random numbers. How does this work?
The Mix
Given two values $a$ and $b$ we can use the mix
function to linearly interpolate between them:
The amt
is a typically a value from $[0,1]$ though it can be less than or greater. Mix is calculated as (1-amt)*a + amt*b
. Note that in glsl code the variables a
and b
can be floating point numbers or vectors.
In the noise
function, we use u.x
, which is the smoothstepped fractional component in the $x$ direction. Lets mix the bottom left an bottom corners of the grid, and then do the same with the top left and top right corners of the tile:
Finally, we can use bilinear interpolation the find a value anywhere inside that rectangle by mixing these two linear mixes, using u.y
, which is the smoothstepped fractional component in the $y$ direction.
In summary, the noise
function uses smoothstep to mix random values along the bottom (a-b) and top (c-d) edges of a rectangle, and then mixes those two mixed values.