---
title: @vgpu/wgsl-std/noise
description: Pure WGSL Voronoi noise primitives for resolver-managed shaders. Import these when you need nearest and second-nearest jittered feature-cell distances without adding bindings or policy-specific styling. For smooth, non-cellular fields and fBM, use @vgpu/wgsl-std/noise/perlin or @vgpu/wgsl-std/noise/simplex instead.
---

# @vgpu/wgsl-std/noise



> **Want fBM, clouds, terrain, fog or plasma? You are on the wrong page.** This module is Voronoi
> (cellular) noise and ships **no fBM helper** — do not hand-roll octaves on top of it. Use
> `@vgpu/wgsl-std/noise/perlin` (`fbmPerlin2d`/`fbmPerlin3d`) or `@vgpu/wgsl-std/noise/simplex`
> (`fbmSimplex2d`/`fbmSimplex3d`): separate subpaths, amplitude-normalized, guaranteed `(-1, 1)`.
> `npx vgpu docs cat /@vgpu/wgsl-std/noise/perlin/index.docs.md`. Stay here only for cells, edges
> (`f2 - f1`) and per-cell IDs (`cell`).

## Import

```wgsl
import { VoronoiSample2, VoronoiSample3, voronoi2d, voronoi3d } from "@vgpu/wgsl-std/noise";
```

## Signature

```wgsl
export struct VoronoiSample2 {
  f1: f32,
  f2: f32,
  cell: vec2i,
}

export struct VoronoiSample3 {
  f1: f32,
  f2: f32,
  cell: vec3i,
}

export fn voronoi2d(position: vec2f) -> VoronoiSample2;
export fn voronoi3d(position: vec3f) -> VoronoiSample3;
```

## Parameters

| Param    | Type    | Required | Default | Notes                                                                                                     |
| -------- | ------- | -------- | ------- | --------------------------------------------------------------------------------------------------------- |
| position | `vec2f` | ✔        | —       | 2D sample position for `voronoi2d`. The function searches the `3 x 3` cells around `floor(position)`.     |
| position | `vec3f` | ✔        | —       | 3D sample position for `voronoi3d`. The function searches the `3 x 3 x 3` cells around `floor(position)`. |

`VoronoiSample2` fields:

| Param | Type    | Required | Default | Notes                                                                                                       |
| ----- | ------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| f1    | `f32`   | ✔        | —       | Euclidean distance to the nearest jittered feature point.                                                   |
| f2    | `f32`   | ✔        | —       | Euclidean distance to the second-nearest jittered feature point. `f1 <= f2`.                                |
| cell  | `vec2i` | ✔        | —       | Integer lattice cell containing the nearest feature point. Use it for stable per-cell randomization or IDs. |

`VoronoiSample3` fields:

| Param | Type    | Required | Default | Notes                                                                                                       |
| ----- | ------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| f1    | `f32`   | ✔        | —       | Euclidean distance to the nearest jittered feature point.                                                   |
| f2    | `f32`   | ✔        | —       | Euclidean distance to the second-nearest jittered feature point. `f1 <= f2`.                                |
| cell  | `vec3i` | ✔        | —       | Integer lattice cell containing the nearest feature point. Use it for stable per-cell randomization or IDs. |

**Returns:** `voronoi2d` returns `VoronoiSample2`; `voronoi3d` returns `VoronoiSample3`. The returned sample contains nearest distance `f1`, second-nearest distance `f2`, and the winning feature cell.

**Throws:** These WGSL declarations do not throw. `resolveShader()` can still throw `VGPU-WGSL-SYM-NOEXPORT` for misspelled imports, `VGPU-WGSL-PKG-NOTFOUND` if the package import cannot be resolved, or validation errors such as `VGPU-WGSL-NAGA-UNKNOWN` if caller WGSL is invalid. Because this module imports `@vgpu/wgsl-std/hash`, package resolution must also be able to resolve that package export.

## Examples

```ts
const voronoiWgsl = `
import { voronoi2d } from "@vgpu/wgsl-std/noise";

fn edgeMask(position: vec2f) -> f32 {
  let sample = voronoi2d(position);
  return sample.f2 - sample.f1;
}
`;

console.log(voronoiWgsl.includes("edgeMask"));
```

```ts
const styledVoronoiWgsl = `
import { pcg3d, unitFloat } from "@vgpu/wgsl-std/hash";
import { voronoi3d } from "@vgpu/wgsl-std/noise";

fn animatedCell(position: vec2f, time: f32) -> f32 {
  let sample = voronoi3d(vec3f(position, time));
  return unitFloat(pcg3d(bitcast<vec3u>(sample.cell)).x);
}
`;

console.log(styledVoronoiWgsl.length > 0);
```

```ts
const cloudWgsl = `
import { voronoi3d } from "@vgpu/wgsl-std/noise";

// Prefer fbmPerlin3d/fbmSimplex3d for this look; only stack Voronoi octaves when
// you want the cellular structure to survive. Voronoi has no built-in fBM helper,
// so build the octaves yourself ("@vgpu/wgsl-std/noise/perlin" and
// "@vgpu/wgsl-std/noise/simplex" ship their own amplitude-normalized
// fbmPerlin*/fbmSimplex* instead).
fn cloudFbm(position: vec3f) -> f32 {
  var value = 0.0;
  var amplitude = 0.5;
  var frequency = 1.0;
  for (var octave = 0u; octave < 4u; octave = octave + 1u) {
    let sample = voronoi3d(position * frequency);
    value = value + amplitude * (1.0 - sample.f1);
    frequency = frequency * 2.03;
    amplitude = amplitude * 0.5;
  }
  return value;
}

// Animate by feeding time as the third dimension, and soften the cell edges by
// warping the domain with a lower-frequency sample before the octave loop.
fn clouds(uv: vec2f, time: f32) -> f32 {
  let warp = voronoi3d(vec3f(uv * 0.5, time * 0.1)).f1;
  return cloudFbm(vec3f(uv + vec2f(warp), time * 0.2));
}
`;

console.log(cloudWgsl.includes("cloudFbm"));
```

## Notes

* This module is pure WGSL: it declares no `@group`, no `@binding`, no overrides, no hidden state, and no entry points. It imports only pure hash helpers.
* `@vgpu/wgsl-std` is a dependency of the `vgpu` package, so `import ... from "@vgpu/wgsl-std/noise";` resolves in any project that installed `vgpu` — no separate install. A `VGPU-WGSL-PKG-NOTFOUND` for this package means it is genuinely absent from `node_modules`.
* **This module is Voronoi (cellular) noise only** — it looks like cells, not smooth clouds. For a cloud/plasma/fog look built purely from Voronoi, sum octaves of `1.0 - sample.f1` and warp the domain, as the third example above shows; for an animated version pass time as the `vec3f` Z coordinate. For a smooth, non-cellular gradient noise, use `@vgpu/wgsl-std/noise/perlin` (`perlin2d`/`perlin3d`) or `@vgpu/wgsl-std/noise/simplex` (`simplex2d`/`simplex3d`) instead — both ship their own amplitude-normalized `fbmPerlin*`/`fbmSimplex*` and are separate subpaths so importing this module never pulls them in. Validate the result with pixels (`npx vgpu check`, then a headless render), not by eye.
* Each lattice cell owns one fully jittered feature point in `[0.0, 1.0)^n`, generated by `pcg2d` or `pcg3d` and converted with `unitFloat`.
* The module returns geometric data only. It does not choose colors, edge widths, jitter strength, smoothing curves, animation, or material policy.
* Use `sample.cell` for stable per-cell styling; use `sample.f2 - sample.f1` for Voronoi edge distance patterns.
* **See also:** `@vgpu/wgsl-std/hash`, `@vgpu/wgsl-std/color`, `resolveShader`.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)