Value · 08
Random and noise
随机与噪声 · random-noiseRandom values create variation; a seed makes it repeatable, and interpolated noise makes it continuous.
Calling Math.random() every frame jitters, which can suit deliberate grain but not smooth motion. A fixed seed keeps a layout stable across reloads and screenshots. Value noise interpolates random lattice values into a continuous curve.
Formula
seeded[i] = mulberry32(seed)()
noise(x) = mix(hash(⌊x⌋), hash(⌊x⌋+1),
smoothstep(fract(x)))Parameters
| This page | Mature libraries | |
|---|---|---|
| seed | 7 | —The same seed and sampling order produce the same sequence. |
| scale | 1 | —A larger input scale makes noise vary more densely. |
Doing it well
- Generate layout variation once or derive it from an index;
portfolio-photographerhashes indices for repeatable card poses.www-motion/rewrite/portfolio-photographer/model.js:2–3 - Use interpolated noise for continuous motion instead of assigning an independent random displacement every frame.
- Independent draws are deliberate when irregularity is the point;
shape-trailgives new shapes random initial rotations.www-motion/rewrite/shape-trail/model.js:8
In our cases
random appears in 35 cases and noise in 5, covering 36 distinct cases together. portfolio-photographer hashes indices for stable card placement; shape-trail draws initial rotations as shapes are created. Neither redraws that property every frame.
Used in 36 cases
Reference implementation · basics.js
/** mulberry32: a seeded generator, so screenshots and tests are reproducible. */
export function mulberry32(seed = 1) {
let a = seed >>> 0;
return () => {
a = (a + 0x6d2b79f5) >>> 0;
let t = Math.imul(a ^ (a >>> 15), 1 | a);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
const hash1 = n => { const s = Math.sin(n * 127.1 + 311.7) * 43758.5453; return s - Math.floor(s); };
/** 1D value noise in [0, 1): random values at integers, smoothly interpolated between. */
export function noise1(x, seed = 0) {
const i = Math.floor(x), f = x - i;
const u = f * f * (3 - 2 * f);
return lerp(hash1(i + seed * 101), hash1(i + 1 + seed * 101), u);
}