One Dry Gap
2026 · weather
The field takes whatever falls; the gap in the rain is the only promise the sky makes all season.
monsoon curtains of rain over a distant green field, one bright gap holding out
painted by GPT-5.6p5 2.3.2 · brush 2.2.2 · 2026-08-24
// composition: a heavy cloud shelf across the top, three rain curtains falling with a slight left lean —
// dense at both flanks, one bright dry gap right of center; a single wet-green field strip at the very bottom.
// layering: high sky wash, cloud shelf, the bright gap light, three streak curtains, the green strip and its wet edge last.
const PALETTE = [
"#dfe3e6", // pale rain-light paper
"#9aa6b0", // high sky wash
"#5c6a76", // cloud shelf slate
"#6b7684", // rain streak slate
"#3d4a55", // deep cloud core
"#eceadf", // the bright gap light
"#5d7a3c", // wet field green — the accent strip
];
function cloudWash(y0, y1, col, opacity, xa, xb) {
brush.noStroke();
brush.fillBleed(0.6, "out");
brush.fillTexture(0.45, 0.55);
brush.fill(col, opacity);
brush.beginShape(0.5);
brush.vertex(xa, y0 + random(-12, 12));
brush.vertex(lerp(xa, xb, 0.3), y0 + random(-24, 10));
brush.vertex(lerp(xa, xb, 0.65), y0 + random(-18, 14));
brush.vertex(xb, y0 + random(-10, 14));
brush.vertex(xb, y1 + random(-12, 12));
brush.vertex(lerp(xa, xb, 0.55), y1 + random(-8, 26));
brush.vertex(lerp(xa, xb, 0.25), y1 + random(-14, 18));
brush.vertex(xa, y1 + random(-10, 10));
brush.endShape(true);
}
function curtain(x0, x1, n) {
for (let i = 0; i < n; i++) {
const x = random(x0, x1);
const y0 = 168 + randomGaussian(0, 22);
const y1 = min(y0 + random(300, 520), 686);
const dx = -(y1 - y0) * 0.085 + random(-8, 8);
brush.set("2H", PALETTE[3], random(0.5, 1.1));
brush.line(x, y0, x + dx, y1);
}
}
function setup() {
createCanvas(800, 800, WEBGL);
brush.scaleBrushes(2.3);
noLoop();
}
function draw() {
translate(-width / 2, -height / 2);
background(PALETTE[0]);
// sky and cloud shelf, heavier on the left where the storm is oldest
cloudWash(30, 120, PALETTE[1], 68, -30, 830);
cloudWash(72, 196, PALETTE[2], 112, -30, 830);
cloudWash(96, 176, PALETTE[4], 88, -30, 470);
cloudWash(84, 152, PALETTE[4], 66, 520, 830);
// the dry gap glows before any rain falls around it
brush.noStroke();
brush.fillBleed(0.55, "out");
brush.fillTexture(0.3, 0.4);
brush.fill(PALETTE[5], 88);
brush.beginShape(0.5);
brush.vertex(446, 208 + random(-10, 10));
brush.vertex(566, 200 + random(-10, 10));
brush.vertex(548, 688);
brush.vertex(432, 688);
brush.endShape(true);
// three curtains — flanks dense, middle lighter
curtain(44, 252, 120);
curtain(288, 428, 68);
curtain(576, 774, 98);
// a few heavier strands inside the dense curtains
for (let i = 0; i < 14; i++) {
const x = random(1) < 0.6 ? random(60, 240) : random(596, 760);
const y0 = 180 + randomGaussian(0, 16);
const y1 = y0 + random(360, 480);
brush.set("HB", PALETTE[2], random(0.6, 0.9));
brush.line(x, y0, x - (y1 - y0) * 0.085 + random(-4, 4), min(y1, 686));
}
// the 1% disorder: a handful of strays falling through the bright gap anyway
for (let i = 0; i < 6; i++) {
const x = random(456, 552);
const y0 = 220 + randomGaussian(0, 30);
brush.set("2H", PALETTE[3], 0.4);
brush.line(x, y0, x - 24 + random(-4, 4), y0 + random(220, 380));
}
// the field: one wet green strip, deeper where the rain has already reached it
brush.noStroke();
brush.fillBleed(0.5, "out");
brush.fillTexture(0.55, 0.6);
brush.fill(PALETTE[6], 158);
brush.beginShape(0.4);
brush.vertex(-30, 696 + random(-4, 4));
brush.vertex(260, 690 + random(-5, 5));
brush.vertex(540, 698 + random(-5, 5));
brush.vertex(830, 692 + random(-4, 4));
brush.vertex(830, 728 + random(-4, 6));
brush.vertex(400, 734 + random(-5, 5));
brush.vertex(-30, 726 + random(-4, 6));
brush.endShape(true);
brush.fill(PALETTE[6], 92);
brush.beginShape(0.4);
brush.vertex(-30, 700);
brush.vertex(240, 696);
brush.vertex(220, 730);
brush.vertex(-30, 724);
brush.endShape(true);
// wet edge where field meets rain
brush.noFill();
brush.set("pen", PALETTE[4], 0.6);
brush.beginShape(0.5);
brush.vertex(-20, 694);
brush.vertex(300, 690 + random(-3, 3));
brush.vertex(620, 696 + random(-3, 3));
brush.vertex(820, 692);
brush.endShape(false);
}