@vgpu/wgsl-std4 symbolsView source ↗

Symbols in this topic

@vgpu/wgsl-std/noise

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.

Import

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

Signature

WGSL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

ParamTypeRequiredDefaultNotes
positionvec2f2D sample position for voronoi2d. The function searches the 3 x 3 cells around floor(position).
positionvec3f3D sample position for voronoi3d. The function searches the 3 x 3 x 3 cells around floor(position).

VoronoiSample2 fields:

ParamTypeRequiredDefaultNotes
f1f32Euclidean distance to the nearest jittered feature point.
f2f32Euclidean distance to the second-nearest jittered feature point. f1 <= f2.
cellvec2iInteger lattice cell containing the nearest feature point. Use it for stable per-cell randomization or IDs.

VoronoiSample3 fields:

ParamTypeRequiredDefaultNotes
f1f32Euclidean distance to the nearest jittered feature point.
f2f32Euclidean distance to the second-nearest jittered feature point. f1 <= f2.
cellvec3iInteger 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

TypeScript
1
2
3
4
5
6
7
8
9
10
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"));
TypeScript
1
2
3
4
5
6
7
8
9
10
11
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);
TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const cloudWgsl = `
import { voronoi3d } from "@vgpu/wgsl-std/noise";
 
// Cloud/plasma look: stack octaves of inverted nearest-distance. Voronoi has no
// built-in fBM helper, so build the octaves yourself (for a smooth, non-cellular
// look, "@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.