init
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
# Cellular and Voronoi Noise
|
||||
|
||||
Distance-based noise for organic cell patterns. See `glsl-noise-random-perlin-simplex-cellular-voronoi.md` for random functions.
|
||||
|
||||
## Basic Cellular Noise
|
||||
|
||||
Distance to nearest feature point:
|
||||
|
||||
```glsl
|
||||
float cellularNoise(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
float minDist = 1.0;
|
||||
|
||||
// Check 3x3 neighborhood
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
vec2 neighbor = vec2(float(x), float(y));
|
||||
vec2 point = random2(i + neighbor);
|
||||
vec2 diff = neighbor + point - f;
|
||||
float dist = length(diff);
|
||||
minDist = min(minDist, dist);
|
||||
}
|
||||
}
|
||||
|
||||
return minDist;
|
||||
}
|
||||
```
|
||||
|
||||
## Voronoi with Cell ID
|
||||
|
||||
```glsl
|
||||
vec3 voronoi(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
float minDist = 1.0;
|
||||
vec2 minPoint;
|
||||
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
vec2 neighbor = vec2(float(x), float(y));
|
||||
vec2 point = random2(i + neighbor);
|
||||
vec2 diff = neighbor + point - f;
|
||||
float dist = length(diff);
|
||||
if (dist < minDist) {
|
||||
minDist = dist;
|
||||
minPoint = i + neighbor + point;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns: distance, cell id x, cell id y
|
||||
return vec3(minDist, minPoint);
|
||||
}
|
||||
|
||||
// Color cells by ID
|
||||
vec3 voronoiColor(vec2 st, float scale) {
|
||||
vec3 v = voronoi(st * scale);
|
||||
return vec3(random(v.yz), random(v.yz + 1.0), random(v.yz + 2.0));
|
||||
}
|
||||
```
|
||||
|
||||
## Worley Noise (F1, F2)
|
||||
|
||||
```glsl
|
||||
vec2 worleyNoise(vec2 st) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
float f1 = 1.0; // Nearest
|
||||
float f2 = 1.0; // Second nearest
|
||||
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
vec2 neighbor = vec2(float(x), float(y));
|
||||
vec2 point = random2(i + neighbor);
|
||||
float dist = length(neighbor + point - f);
|
||||
|
||||
if (dist < f1) {
|
||||
f2 = f1;
|
||||
f1 = dist;
|
||||
} else if (dist < f2) {
|
||||
f2 = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vec2(f1, f2);
|
||||
}
|
||||
```
|
||||
|
||||
## Worley Variations
|
||||
|
||||
```glsl
|
||||
float worleyF1(vec2 st) { return worleyNoise(st).x; }
|
||||
float worleyEdges(vec2 st) { vec2 w = worleyNoise(st); return w.y - w.x; }
|
||||
float worleyBlobs(vec2 st) { vec2 w = worleyNoise(st); return w.x * w.y; }
|
||||
```
|
||||
|
||||
## Animated Voronoi
|
||||
|
||||
```glsl
|
||||
float animatedVoronoi(vec2 st, float time) {
|
||||
vec2 i = floor(st);
|
||||
vec2 f = fract(st);
|
||||
|
||||
float minDist = 1.0;
|
||||
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
vec2 neighbor = vec2(float(x), float(y));
|
||||
vec2 point = random2(i + neighbor);
|
||||
// Animate point position
|
||||
point = 0.5 + 0.5 * sin(time + 6.2831 * point);
|
||||
float dist = length(neighbor + point - f);
|
||||
minDist = min(minDist, dist);
|
||||
}
|
||||
}
|
||||
|
||||
return minDist;
|
||||
}
|
||||
```
|
||||
|
||||
## Distance Metrics
|
||||
|
||||
```glsl
|
||||
float euclidean(vec2 v) { return length(v); }
|
||||
float manhattan(vec2 v) { return abs(v.x) + abs(v.y); }
|
||||
float chebyshev(vec2 v) { return max(abs(v.x), abs(v.y)); }
|
||||
```
|
||||
|
||||
## Practical Applications
|
||||
|
||||
```glsl
|
||||
// Cracked ground
|
||||
vec3 crackedGround(vec2 st) {
|
||||
float edges = worleyEdges(st * 5.0);
|
||||
return mix(vec3(0.1), vec3(0.5, 0.4, 0.3), smoothstep(0.0, 0.05, edges));
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user