[/lab/particle-field]

particle field

1,200 points in a sphere, normal-blended, slowly tumbling. one shader, no compute. WebGL 1 fallback safe.

what's interesting

normal blending instead of additive keeps the cloud reading as a single object rather than a glow halo. the sphere-volume distribution uses an inverse CDF trick (cube root of a uniform random for radius) so the density is genuinely uniform — not denser at the center the way a naive position = random() distribution would be.

// uniform-volume distribution within a sphere
const r = Math.cbrt(Math.random()) * RADIUS;
const theta = Math.random() * Math.PI * 2;
const phi = Math.acos(2 * Math.random() - 1);
positions[i * 3] = r * Math.sin(phi) * Math.cos(theta);
positions[i * 3 + 1] = r * Math.sin(phi) * Math.sin(theta);
positions[i * 3 + 2] = r * Math.cos(phi);

the per-particle pulse is driven by the material's opacity rather than a custom shader uniform, because pointsMaterial already covers what i needed and a custom shader would have meant another file. this is one of those "don't write more code than the demo requires" judgement calls.