SKILL.md
Harmonic Perlin Gradients
Overview
Generate procedural color fields by mapping Perlin noise values to a color palette through thresholds derived from harmonic music interval ratios (just intonation). The musical structure determines where colors transition; the noise determines the shape of those transitions.
When to Use
- Generating gradients from a sampled image palette
- Creating procedural textures/landscapes with musical proportions
- Batch-generating themed color fields with systematic variation
- Any "color + noise + music theory" combination
Core Pattern
1. Extract palette from source image (dark → light, 15-21 colors)
2. Choose harmonic interval (chord, scale, series)
3. Normalize frequency ratios to [0,1] thresholds
4. Render Perlin noise field, map noise values to palette via thresholds
5. Interpolate between adjacent palette colors for smooth blending
Quick Reference: Harmonic Intervals → Positions
| Interval |
Ratios |
Normalized positions |
| Octave |
1, 2 |
0.0, 1.0 |
| Perfect Fifth |
1, 3/2, 2 |
0.0, 0.5, 1.0 |
| Major Triad |
4, 5, 6 |
0.0, 0.5, 1.0 |
| Minor Triad |
10, 12, 15 |
0.0, 0.4, 1.0 |
| Major 7th |
8, 10, 12, 15 |
0.0, 0.286, 0.571, 1.0 |
| Dominant 7th |
4, 5, 6, 7 |
0.0, 0.333, 0.667, 1.0 |
| Minor 7th |
10, 12, 15, 18 |
0.0, 0.25, 0.625, 1.0 |
| Diminished 7th |
2^(0/12), 2^(3/12), 2^(6/12), 2^(9/12) |
Equal spacing |
| Augmented |
2^(0/12), 2^(4/12), 2^(8/12) |
Equal spacing |
| Sus4 |
6, 8, 9 |
0.0, 0.667, 1.0 |
| Major Pentatonic |
1, 9/8, 5/4, 3/2, 5/3, 2 |
0.0, 0.125, 0.25, 0.5, 0.667, 1.0 |
| Minor Pentatonic |
1, 6/5, 4/3, 3/2, 9/5, 2 |
0.0, 0.2, 0.333, 0.5, 0.8, 1.0 |
| Whole Tone |
2^(i/6) for i=0..6 |
Equal spacing |
| Harmonic Series |
1, 2, 3, ..., N |
Clusters toward low end |
| Overtone Scale |
1, 9/8, 5/4, 11/8, 3/2, 13/8, 7/4, 2 |
Non-uniform |
Normalization formula: position = (ratio - min) / (max - min)
Noise Modes and Their Character
| Mode |
Character |
Best for |
Key params |
fbm |
Smooth, gradient-like |
Soft fields, horizons |
scale 1.0-2.0, octaves 1-2 |
warp |
Organic, flowing |
Marble, lava, clouds |
warpAmt 1.0-3.0 |
ridge |
Sharp peaks, veins |
Mountains, cracks |
gain 0.5-0.65, high octaves |
turbulence |
Billowy, cellular |
Storms, plasma |
high octaves, abs(fbm) |
terraced |
Flat plateaus, topo map |
Strata, contour maps |
terraceSteps 5-12 |
Tuning Parameters
Smoothness (gradient-like → textured):
octaves: 1 = ultra smooth, 2 = soft, 4+ = detailed
scale: lower = broader features, higher = finer
gain: lower = smoother falloff between octaves
Contrast (matte → dramatic):
gamma: 1.0 = linear, <0.7 = high contrast, >1.2 = washed
- Palette index spacing: adjacent indices = subtle, wide jumps = dramatic
Directionality:
vBias: 0.3-0.7 adds vertical gradient (horizon effect)
- Negative vBias inverts (bright top, dark bottom)
Palette Extraction Guidelines
Sample 15-21 colors from source image ordered dark to light. Include:
- 3-4 darkest tones (shadows/background)
- 8-10 midtones (dominant color range)
- 3-4 highlights (brightest areas)
Space colors perceptually even. Adjacent palette entries should look distinct but not jarring.
Color Index Selection Per Gradient
Match palette range to musical mood:
| Mood |
Palette indices |
Example interval |
| Bright, open |
Mid-to-high (8-20) |
Major triad, pentatonic |
| Warm, muted |
Mid-range (5-17) |
Dominant 7th, sus4 |
| Deep, moody |
Low-to-mid (2-14) |
Minor triad, minor 7th |
| Full range |
Spanning (0-20) |
Harmonic series, overtone |
| Soft, pastel |
High only (10-20) |
Augmented, whole tone |
Implementation Structure
The generator produces self-contained HTML files with inline JS:
- Python script (
generate_15.py): defines palette, intervals, noise config per gradient
- HTML template: contains Perlin noise implementation, fbm/warp/ridge functions, rendering loop
- Output: standalone HTML files, one per gradient
Key JS functions in template: perlin(x,y), fbm(x,y,...), warp(x,y,...), ridge(x,y,...)
Common Mistakes
| Mistake |
Fix |
| All gradients look the same |
Vary octaves, scale, vBias, and palette range per gradient |
| Too dark / no highlights |
Ensure palette indices reach into the light end (16+) |
| Too washed out / no contrast |
Use wider palette index jumps or lower gamma |
| Smoky / liquidy appearance |
Use plain fbm with octaves 1-2 instead of warp |
| Sharp banding between colors |
Ensure smooth interpolation between adjacent threshold colors |
| Noise too fine / busy |
Lower scale (1.0-2.0) and octaves (1-2) |