Noise Functions

14 / 15
Learn and implement common noise functions in GLSL, such as random noise, value noise, and gradient noise (like a simplified version of Perlin noise), used for generating various procedural textures and effects.

Procedural noise needs to be "random but continuous" — neighboring pixels should be similar, with smooth large-scale variation. Value Noise is the most fundamental way to achieve this:


How value noise works

Divide the plane into a regular grid. Assign a pseudo-random value to each grid corner (integer coordinate). The current pixel falls somewhere inside a grid cell — take the four corner values and interpolate between them with a smooth curve. That is value noise.

floor(st) extracts the grid corner (integer part). fract(st) gives the pixel's position inside the cell (0 to 1).


Why use ff(3-2f) instead of linear interpolation

Linear interpolation with f directly produces visible creases at grid boundaries because the derivative is discontinuous there.

f * f * (3.0 - 2.0 * f) is the smooth step polynomial — it has a zero derivative at both 0 and 1, so the transition is smooth with no visible seams. This is the core quality difference between noisy-looking and smooth value noise.


Three noise types side by side

  • Left panel: Random noise (random(pos * 10.0)) — pixels are fully independent, looks like TV static
  • Middle panel: Value noise (valueNoise(pos)) — smooth, continuous blobs where neighboring pixels are correlated
  • Right panel: Gradient noise (perlinNoise(pos)) — more natural than value noise, more uniform contrast

Try changing it

ChangeEffect
pos * 5.0pos * 10.0Double frequency, smaller patches
pos * 5.0pos * 2.0Half frequency, larger patches
u_time * 0.5u_time * 2.0Faster scrolling
Change f*f*(3.0-2.0*f) back to fValue noise shows visible creases at grid edges

Exercise

In the valueNoise function, try changing vec2 u = smoothstep(0.0, 1.0, f); to the equivalent polynomial f * f * (3.0 - 2.0 * f) and verify the result looks the same.

Answer Breakdown

smoothstep(0.0, 1.0, f) and f * f * (3.0 - 2.0 * f) are mathematically identical — smoothstep uses this polynomial internally. Both produce a zero derivative at f=0 and f=1, giving a seam-free transition.

Writing the polynomial directly makes it explicit that a smooth interpolation is happening, without relying on how the GPU implements smoothstep. In practice both forms work equally well.

Try stacking two octaves manually: valueNoise(pos) * 0.5 + valueNoise(pos * 2.0) * 0.25 to see a hand-built FBM effect.

GLSL Code Editor

Correct Code Preview

Current Code Preview