Compare with
v1 (Fractal Clouds):
v1 builds each cloud from N random SWEllipse puffs.
The ellipses have hard mathematical boundaries you can see at cloud
edges — giving that slightly "cartoonish" look.
v2 fixes all three root causes with new techniques.
Fix 1 — Genuine fractal shape: fBm
fBm(x, y) = Σk=0N-1
noise(x·2k, y·2k)
× (1/2)k·H
fBm (fractional Brownian motion) sums
N octaves of Perlin noise, each at double the spatial
frequency and (1/2)H times the amplitude of
the previous. Because it adds detail at every scale — large-scale
shape from octave 1, medium lumps from octave 3, tiny edge turbulence
from octave 5 — the cloud boundary is a true fractal
isocurve. It looks statistically the same whether you
zoom in or out, just like a real cloud silhouette.
Random candidate positions are scattered inside each cloud’s
bounding ellipse (a Poisson-like scatter, not a regular grid — grids
produced visible horizontal bands). A candidate becomes a puff only
where fBm(x, y) × radial_mask > threshold.
The threshold is the Cloud Cover slider;
the number of cloud objects is the separate
Cloud Count slider.
Fix 2 — No hard edges: radial gradient puffs
Each puff is drawn using
drawingContext.createRadialGradient() — fully
opaque at the center, smoothly fading to transparent at the edge
radius. There are no solid fills and no SWEllipse outlines anywhere.
Overlapping gradients blend together just like the water droplets
in a real cloud merge into a continuous mass.
Fix 3 — Physical lighting: top-lit color model
Each puff is colored by its vertical position within the cloud.
The top receives direct sunlight → near pure white (strong Mie
forward-scattering). The bottom is in self-shadow → cool blue-gray
(sky light scattered from below). This gradient is the single
most important cue your eye uses to perceive a cloud as
three-dimensional.
The Octaves slider — watch the fractal emerge
- 1 octave — smooth rounded blobs (single-scale, like v1)
- 2–3 octaves — cloud lobes start appearing
- 4–5 octaves — convincingly natural boundaries
- 6–7 octaves — wispy tendrils at every edge
- 8–9 octaves — maximum fractal detail
The Hurst Exponent H
- Low H (0.15–0.30) — high-frequency octaves contribute
nearly as much as low-frequency ones → extremely jagged, turbulent edges
- Mid H (0.50–0.75) — balanced mix; typical cumulus
- High H (0.90–0.99) — high-frequency octaves fade out
quickly → smooth, puffy fair-weather cumulus
- H = 0.75 — default; sweet spot for mid-latitude cumulus
Depth layers & parallax (same as v1)
- Far layer — upper sky, small, hazy opacity, slowest drift
- Mid layer — middle sky, medium size and speed
- Near layer — lower sky, large, bright, fastest drift
Cloud Count vs. Cloud Cover — two independent controls
These sliders control coverage at different levels of the system:
- Cloud Count (2–50) — the total number of cloud
objects distributed across the three depth layers.
Each object is an independent fBm-shaped mass that drifts
at its own speed. More objects = more sky covered.
- Cloud Cover / Threshold (0.00–0.80) — the fBm
density threshold inside each cloud object. Lower
values accept more candidate puff positions, making each
individual cloud denser and puffier. At 0.00 every
candidate inside the bounding ellipse is accepted.
Heavy overcast recipe:
Cloud Count → 35–50 + Cover Threshold → 0.00–0.15
At a low threshold alone the sky can still look partly
cloudy because only 12 cloud objects exist with gaps between them.
Raising the count fills those gaps; lowering the threshold then
packs each individual cloud solid.