Skip to content

Noise

Procedural noise is the workhorse of generative shading: a deterministic pseudo-random field you can sample anywhere to drive textures, displacement, clouds, terrain, fluid motion, and more. Every entry below is a single pure WGSL function in the registry. Pull one into a composition by slug, then call it from your fragment stage:

let main = r#"
@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
let n = simplex2(in.uv * 6.0) * 0.5 + 0.5;
return vec4<f32>(n, n, n, 1.0);
}
"#;
let shader = Shader::new(&["noise/simplex2", main])?;

Each preview below renders the field directly on a UV grid, scaled so the features are clearly visible. Output ranges vary — value-style functions land in [0, 1), gradient/simplex variants in roughly [-1, 1], and the multi- octave family (fbm, ridged, turbulence) sums into wider ranges that you may want to saturate or remap before shading.

2D curl noise — a divergence-free 2D vector field derived from a scalar potential. Useful for fluid-like motion and particle advection.

fn curl2(p: vec2<f32>) -> vec2<f32>

noise/curl2 preview

2D fractal Brownian motion: stacked octaves of value noise with halving amplitude. Output sums to roughly [0, 1] for typical octave counts.

fn fbm2(p: vec2<f32>, octaves: u32) -> f32

noise/fbm2 preview

3D fractal Brownian motion. Sample on a fixed slice (e.g. z = 0) for a 2D look, or animate z for a smooth time evolution.

fn fbm3(p: vec3<f32>, octaves: u32) -> f32

noise/fbm3 preview

2D gradient (Perlin-style) noise in roughly [-1, 1]. Smooth derivatives make this a good choice for displacement and bump mapping.

fn gradient2(p: vec2<f32>) -> f32

noise/gradient2 preview

2D ridged multifractal — fbm built from 1 - |noise|. Produces crisp mountain-ridge patterns; great for terrain and lightning.

fn ridged2(p: vec2<f32>, octaves: u32) -> f32

noise/ridged2 preview

2D simplex noise in roughly [-1, 1] (Ashima-style). Cheaper and less grid-aligned than gradient noise; the default choice for most shaders.

fn simplex2(p: vec2<f32>) -> f32

noise/simplex2 preview

2D turbulence: fbm built from |noise|, giving sharper creases than plain fbm. Classic for flame, smoke, and marble.

fn turbulence2(p: vec2<f32>, octaves: u32) -> f32

noise/turbulence2 preview

2D value noise in [0, 1). Hash-and-interpolate; fastest of the smooth noises, with visibly grid-aligned features.

fn value2(p: vec2<f32>) -> f32

noise/value2 preview

3D value noise in [0, 1). Sample on a slice for a 2D look, or animate the third axis for time-evolving fields.

fn value3(p: vec3<f32>) -> f32

noise/value3 preview

2D Worley (cellular) noise. Returns the distances (F1, F2) to the nearest and second-nearest feature points — common patterns are F1 for cells, F2 - F1 for edges.

fn worley2(p: vec2<f32>) -> vec2<f32>

noise/worley2 preview