threejs-procedural-fields skill (Threejs-Awesome-Graphics-Agent-Skills)
- Install
- SKILL.md (verbatim)
- Field contract
- Required workflow
- Non-negotiable rules
- Routing boundary
- Other files in this skill
- references/field-stack-recipes.md (verbatim)
- Contents
- Stable coordinate ownership
- Planetary sphere fields
- Altitude filtering
- Wetness-coupled game terrain
- Shared-phase water fields
- Structured stochastic placement
- Cross-system implementation contract
- Diagnostics
What it does. Build coherent procedural scalar and vector fields for Three.js materials and geometry. Use for terrain, planets, wear, biomes, clouds, water masks, displacement, roughness, normals, domain warping, and any visual where several channels must derive from shared causes. Part of scottstts/Threejs-Awesome-Graphics-Agent-Skills (scottstts/Threejs-Awesome-Graphics-Agent-Skills).
| Upstream | scottstts/Threejs-Awesome-Graphics-Agent-Skills |
| Skill file | skills/threejs-procedural-fields/SKILL.md |
| License | MIT |
| Author | Scott Sun (scottstts) |
| Fetched | 2026-09-10 |
Install
npx skills add scottstts/Threejs-Awesome-Graphics-Agent-Skills --skill threejs-procedural-fields, or copy the skill folder into~/.claude/skills/threejs-procedural-fields/.- Raw file:
curl -sL https://raw.githubusercontent.com/scottstts/Threejs-Awesome-Graphics-Agent-Skills/HEAD/skills/threejs-procedural-fields/SKILL.md
SKILL.md (verbatim)
name: threejs-procedural-fields
description: Build coherent procedural scalar and vector fields for Three.js materials and geometry. Use for terrain, planets, wear, biomes, clouds, water masks, displacement, roughness, normals, domain warping, and any visual where several channels must derive from shared causes.
Procedural Fields
Do not start by stacking noise. Start by defining the fields the object physically or stylistically needs.
Field contract
Before shader code, write a field bundle:
coordinates
→ macro form
→ meso structure
→ derived causes
→ material channels
Example:
sphereDirection
→ warpedDirection
→ elevation + ridges + craterDepth
→ slope + cavity + latitude + moisture
→ biome + color + roughness + bump
Required workflow
- Choose coordinates that remain stable under camera and object motion.
- Lock real or perceptual scale for each frequency band.
- Create named primary fields. Never hide the whole look in one expression.
- Derive secondary fields from causes: slope from normals, shore from sea-level distance, wear from exposure, dirt from cavity.
- Reuse the same fields across color, roughness, normal, displacement, emission, and scattering.
- Add debug output for every named field.
- Filter high-frequency fields by derivatives, tessellation density, or camera distance.
Read references/field-stack-recipes.md before implementation. It records sphere, terrain, water, and structured-placement field contracts plus common parity defects.
Read the procedural planet surface for a shared CPU/GLSL field bundle whose height, continents, climate, biomes, roughness, and normals remain independently inspectable.
Non-negotiable rules
- Independent noise per channel produces visual soup. Share structure.
- Domain warp the coordinates, not every result.
- Warp spherical coordinates tangentially, then renormalize.
- Use different frequency bands for silhouette, regions, surface breakup, and micro-normal.
- Do not displace geometry with frequencies the mesh cannot represent.
- Keep categorical masks broad enough to avoid isolated “bubble” regions.
- Parameter names must describe perception:
ridgeWidth,coastBlend,cavityDarkening, notnoise3Amount.
Routing boundary
Use this skill when the shared field model is the task. Use
$threejs-procedural-materials when the task is channel assembly and material
response, and $threejs-procedural-planets when the deliverable is a complete
planetary body.
Other files in this skill
references/field-stack-recipes.md (verbatim)
Procedural field-stack recipes
Use this reference to construct coherent field bundles for spherical terrain, altitude-filtered detail, terrain wetness, water optics, and structured stochastic placement.
Contents
- Stable coordinate ownership
- Planetary sphere fields
- Altitude filtering
- Wetness-coupled game terrain
- Shared-phase water fields
- Structured stochastic placement
- Cross-system implementation contract
- Diagnostics
Stable coordinate ownership
The strongest common rule is that one stable coordinate domain owns related visual channels.
Planetary terrain materials store normalized undeformed sphere direction in a
surfaceDirection attribute. Terrain shader fields sample:
terrainCoordinateKm = normalize(surfaceDirection) * radiusKm
They do not sample the interpolated displaced position. This prevents noise stretching over steep relief and allows orbit/close-detail filtering in the same kilometer domain.
Wetness-coupled game terrain samples positionWorld, because wetness is tied
to a world water height. Open-water surfaces likewise sample world XZ so near
tiles and far ocean quads share wave phase.
Choose coordinates from the cause:
planet geology -> undeformed radial direction * physical radius
water/wetness -> shared world plane
tree growth -> branch-local longitudinal and radial coordinates
Planetary sphere fields
A planet-scale material performs tangential warp:
warp = three seeded noise channels - 0.5
tangentWarp = warp - radial * dot(warp, radial)
warpAmplitudeKm = max(radiusKm * 0.012, 36)
warped = normalize(terrainKm + tangentWarp * warpAmplitudeKm) * radiusKm
Its broad terrain synthesis uses separated bands:
macro A frequency = 0.00034, weight 0.52
macro B frequency = 0.00092, internal scale 0.52, weight 0.33
ridge frequency = 0.0029, weight 0.25
crater-like frequency = 0.0069, exponent 2.9
The CPU geometry uses a different deterministic value-noise stack:
continental: 5 octaves, lacunarity 2.03, gain 0.50
highlands: 4 octaves, lacunarity 2.15, gain 0.55
ridges: 4 octaves, lacunarity 2.08, gain 0.52
crater-like: 3 octaves, pow(1 - noise, 3.2)
This mismatch is an observed defect, not a recommended pattern. The material
mixes only 8% actual geometry displacement into shader macro height. A new
implementation should share one deterministic field or validate CPU/GPU parity
at fixed sphere directions. The procedural-planet-surface example under
$threejs-procedural-planets demonstrates the shared-field form: one
deterministic sharedTerrain stack evaluated identically for CPU displacement
and GLSL shading.
Derived climate causes in this field stack:
humidity =
0.65 * broadNoise(0.0022)
+ 0.35 * detailNoise(0.0075)
temperature =
(1 - abs(latitude)^1.35) * 0.85
+ 0.15
- macroHeight * 0.32
slope =
1 - abs(dot(localNormal, radialDirection))
Snow, arid, lush, and rock masks combine those fields with altitude, ridges, and a smaller jitter field. The important mechanism is causal reuse, not the specific color palette.
Altitude filtering
The same planetary material computes:
cameraAltitude = max(distance(camera, center) - radius, 0)
detailAltitude = min(cameraAltitude, externally supplied detail altitude)
near = max(radius * 0.022, 6.5)
mid = max(radius * 0.11, 24)
far = max(radius * 0.50, 140)
nearWeight = 1 - smoothstep(near, mid, detailAltitude)
farWeight = smoothstep(mid, far, detailAltitude)
midWeight = clamp(1 - nearWeight - farWeight, 0, 1)
These weights attenuate bump, coastline sharpness, wave detail, clearcoat, and micro material variation. The frequencies remain stable; contribution fades.
Wetness-coupled game terrain
A stylized game terrain material uses three world-space noise bands:
noise1: position * (0.2, 1, 0.2), amplitude 0.05, bias 0.2
noise2: position * 9, amplitude 0.4, bias 0.5
noise3: position * (14, 3, 14), amplitude 2, bias 0.5
soilNoise = noise1 + noise2 + noise3
Surface identity derives from geometry orientation:
grassness = smoothstep(0.01, 1, normalWorld.y^1.6)
color = mix(soilColor, grassColor, grassness)
The same identity blends soil and grass roughness fields. World height adds a wetness response near the water level:
wetness = smoothstep(-1, -7, positionWorld.y) * noise1 * 3.5
roughness -= wetness
The reversed-looking edges are intentional, but GLSL leaves smoothstep
undefined when edge0 > edge1. Write it as 1 - smoothstep(-7, -1, y) for
portable behavior.
Shared-phase water fields
An open-water field bundle evaluates six directional wave bands in one function and returns:
RGB = analytic normal from summed gradients
A = crest metric derived from the same slopes and phases
Wavelengths:
12, 6, 2.5, 5.25, 3.0, 1.5 world units
Amplitudes relative to the base:
1.0, 0.55, 0.22, 0.12, 0.08, 0.05
The three smallest bands are attenuated from screen derivatives using their
wavenumbers. Foam consumes the returned crest metric; it does not sample an
unrelated scrolling mask. The analytic-wave-optics example under
$threejs-water-optics applies the same contract: resolvedNormalAndCrest()
returns the resolved normal and crest from one evaluation and attenuates its
three smallest bands by their derivative footprint.
Structured stochastic placement
The structured-ash-growth example under $threejs-procedural-vegetation
demonstrates a different kind of field: constrained discrete placement. Child
branches use stratified longitudinal slots and independently permuted angular
slots. Randomness selects within valid slots rather than choosing every
position freely.
That same mechanism applies to:
branch emergence
façade variants
particle burst directions
crater distribution
cloud-cell placement
When a pattern must remain authored, stratify the domain before applying random jitter.
Cross-system implementation contract
Before coding, record:
coordinate domain
physical/perceptual units
primary fields
derived causes
consuming channels
filtering rule
CPU/GPU parity requirement
seed ownership
Reject a field stack when:
- color, roughness, and normal use unrelated structure;
- geometry and shading claim the same feature but evaluate different functions;
- a categorical mask is only a narrow noise threshold;
- high-frequency terms survive after their projected footprint is subpixel;
- world effects use object coordinates or planetary effects use flat world Y;
- random placement has no strata, budget, or semantic constraints.
Diagnostics
Expose:
source coordinates
tangential warp vector
each frequency band
actual geometry height versus shader height
humidity, temperature, slope, and identity masks
near/mid/far weights
water normal and crest from the same evaluation
wetness by world height
seed and stratification cells
Back to scottstts/Threejs-Awesome-Graphics-Agent-Skills or Agent skills.