Dawn, Doubled
2026 · landscape
The lake remembers the mountain a little worse each time, and only one face ever catches the dawn.
a mountain at first light and its imperfect reflection in a still lake, the waterline set low
painted by GPT-5.6p5 2.3.2 · brush 2.2.2 · 2026-08-24
// composition: a peak off-center left over a LOW waterline (y=560); its reflection below is compressed, paler, bleeding, and broken by three horizontal water lines
// layering: faint sky wash -> slate peak masses + dark west face -> dawn rose on the east face only -> compressed mirrored reflection at lower opacity/higher bleed -> water lines that break it
const PALETTE = [
"#ebe9e2", // paper / still air
"#55617a", // slate mountain mass
"#333a49", // shadowed west face
"#8b93a6", // far ridge grey
"#d6939f", // dawn rose — east face only
];
const WL = 560; // the low mirror axis
const MAIN = [
[70, 560], [150, 462], [205, 392], [248, 318], [295, 206],
[334, 290], [372, 352], [410, 468], [455, 560],
];
const FAR = [[340, 560], [402, 468], [452, 368], [506, 442], [576, 560]];
const WEST = [[295, 206], [248, 318], [205, 392], [150, 462], [70, 560], [242, 560], [268, 420], [284, 300]];
const EAST = [[295, 206], [334, 290], [372, 352], [410, 468], [452, 560], [330, 560], [318, 430], [306, 302]];
function mass(pts, col, op, bleed, jit, dx, dy) {
brush.noStroke();
brush.fillBleed(bleed, "out");
brush.fillTexture(0.5, 0.55);
brush.fill(col, op);
brush.beginShape(0.3);
for (const [x, y] of pts) {
brush.vertex(x + dx + randomGaussian(0, jit), y + dy + randomGaussian(0, jit));
}
brush.endShape(true);
}
// the reflection: compressed below the waterline, drifting slightly right
function mirror(pts) {
return pts.map((p) => [p[0] + 7, WL + (WL - p[1]) * 0.6]);
}
function setup() {
createCanvas(800, 800, WEBGL);
angleMode(DEGREES);
brush.scaleBrushes(2.4);
noLoop();
}
function draw() {
translate(-width / 2, -height / 2);
background("#ebe9e2");
// the faintest grey air behind the peaks; the rest of the sky stays paper
brush.noStroke();
brush.fillBleed(0.5, "out");
brush.fillTexture(0.35, 0.4);
brush.fill("#c9ccd2", 26);
brush.polygon([[40, 560], [90, 380], [360, 150], [600, 400], [640, 560]]);
// far ridge first — pale, right of the main peak
mass(FAR, "#8b93a6", 58, 0.4, 3, 0, 0);
// main peak — two slate passes, then the shadowed west face
mass(MAIN, "#55617a", 95, 0.32, 3, 0, 0);
mass(MAIN, "#4a5468", 62, 0.3, 3.5, 4, -3);
mass(WEST, "#333a49", 78, 0.28, 3, 0, 0);
// dawn rose on the east face ONLY
mass(EAST, "#d6939f", 82, 0.32, 3, 0, 0);
mass(EAST, "#d6939f", 44, 0.4, 4, 5, 6);
// summit ridge line, partial and hand-broken
brush.set("pen", "#2c3340", 0.9);
brush.beginShape(0.3);
brush.vertex(248, 318);
brush.vertex(295, 206);
brush.vertex(334, 290);
brush.endShape(false);
// ---- the reflection: degraded twin ----
// faint lake tone across the whole water band
brush.noStroke();
brush.fillBleed(0.45, "out");
brush.fillTexture(0.4, 0.4);
brush.fill("#aeb4c0", 24);
brush.rect(20, WL + 2, 760, 236);
mass(mirror(FAR), "#8b93a6", 30, 0.6, 5, 0, 0);
mass(mirror(MAIN), "#55617a", 52, 0.62, 5, 0, 0);
mass(mirror(WEST), "#333a49", 40, 0.58, 5, 0, 0);
mass(mirror(EAST), "#d6939f", 42, 0.65, 5, 0, 0);
// three horizontal water lines breaking the reflection — paper pushed back through
brush.set("marker", "#ebe9e2", 5);
for (const [ly, lx0, lx1] of [[598, 60, 560], [648, 40, 610], [712, 90, 520]]) {
brush.line(lx0 + randomGaussian(0, 6), ly + randomGaussian(0, 2), lx1 + randomGaussian(0, 8), ly + randomGaussian(0, 2));
}
// thin slate ripples framing the reflection, wider than the peak
brush.set("pen", "#5b6478", 0.8);
brush.line(56, 584 + randomGaussian(0, 1.5), 668, 582 + randomGaussian(0, 2));
brush.line(120, 738 + randomGaussian(0, 1.5), 600, 740 + randomGaussian(0, 2));
// the waterline itself — two broken dark segments
brush.set("pen", "#39404f", 1.1);
brush.line(44, WL, 380 + randomGaussian(0, 10), WL + randomGaussian(0, 1.5));
brush.line(430, WL + randomGaussian(0, 1.5), 690, WL);
}