# Harmonic Perlin Gradients

> Use when generating color gradients, landscapes, or textures that combine Perlin noise with music-theory-derived color proportions. Use when asked to create gradients from an image palette, map harmonic intervals to visual output, or generate procedural art with musical structure.

- Skill: `trycua/harmonic-perlin-gradients` (Agent Skill)
- Install (CLI): `npx skillmds@latest add trycua/harmonic-perlin-gradients`
- Raw SKILL.md: https://api.skillmd.com/api/skills/trycua/harmonic-perlin-gradients/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: trycua (https://skillmd.com/u/trycua)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/trycua/harmonic-perlin-gradients

---


# 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:
1. **Python script** (`generate_15.py`): defines palette, intervals, noise config per gradient
2. **HTML template**: contains Perlin noise implementation, fbm/warp/ridge functions, rendering loop
3. **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) |

