Crevasse Field
2026 · landscape
The ice keeps its own ledger of slow pressure, and the cracks are where it finally speaks.
diagonal ice strata torn by stepped crevasses, one shoulder of rock breaking through
painted by GPT-6 Astrap5 2.3.2 · brush 2.2.2 · 2026-08-24
// composition: a crevasse field — ice strata run as long diagonal bands upper-left to lower-right; dark stepped cracks concentrate center-right; upper-left stays clean ice
// layering: pale diagonal strata, quiet snow shelf, blue crevasse walls and their lit lips, snow-grain, one warm rock shoulder.
const PALETTE = [
"#eef3f4", // paper / clean ice
"#c7dfe6", // pale cyan strata
"#b5d3dc", // deeper ice band
"#17434c", // crevasse shadow teal
"#a8713f", // warm rock exposure — the single accent
];
// Each fissure has a sunward lip, a blue wall and a narrow, tapering throat.
// The width belongs to the pressure field, rather than to the drawing pen.
const iceFissure = (pts, breadth) => {
const rim = pts.map(([x, y], i) => {
const t = i / (pts.length - 1);
const opening = breadth * Math.pow(Math.sin(Math.PI * t), 0.7);
return [x + opening, y + opening * 0.43];
});
brush.noStroke();
brush.fillBleed(0.3, "out");
brush.fillTexture(0.55, 0.46);
brush.fill(PALETTE[2], 170);
brush.polygon([...pts, ...rim.slice().reverse()]);
for (let i = 0; i < pts.length - 1; i++) {
const a = pts[i], b = pts[i + 1], c = rim[i + 1], d = rim[i];
brush.noStroke();
brush.fillBleed(0.22, "out");
brush.fill(PALETTE[3], 150);
brush.polygon([a, b, [lerp(b[0], c[0], 0.38), lerp(b[1], c[1], 0.38)],
[lerp(a[0], d[0], 0.38), lerp(a[1], d[1], 0.38)]]);
brush.noFill();
brush.set("cpencil", PALETTE[3], 0.65 + breadth * 0.023);
brush.line(a[0], a[1], b[0], b[1]);
if (i > 0 && i < pts.length - 2) {
brush.set("2H", "#7fa9b6", 0.65);
for (let j = 1; j < 5; j++) {
const t = j / 5;
brush.line(lerp(a[0], b[0], t) + 3, lerp(a[1], b[1], t) + 2,
lerp(d[0], c[0], t), lerp(d[1], c[1], t));
}
brush.set("cpencil", PALETTE[0], 1.8);
brush.line(d[0] + 2, d[1] - 2, c[0] + 2, c[1] - 2);
}
}
};
function setup() {
createCanvas(800, 800, WEBGL);
angleMode(DEGREES);
brush.scaleBrushes(2.4);
noLoop();
}
function draw() {
translate(-width / 2, -height / 2);
background("#eef3f4");
// a quiet ice-blue tint over the whole sheet — no bare paper anywhere
brush.noStroke();
brush.fillBleed(0.4, "out");
brush.fillTexture(0.35, 0.3);
brush.fill("#ddedf0", 55);
brush.rect(-30, -30, 860, 860);
// strata — long parallel band washes in a rotated frame
push();
translate(400, 400);
rotate(38);
const bandCols = ["#c7dfe6", "#b5d3dc", "#ddedf0"];
for (let i = 0; i < 19; i++) {
const d = -500 + i * 55 + randomGaussian(0, 6);
const w = random(22, 56);
const op = constrain(78 + randomGaussian(0, 20) + i * 2.4, 50, 160);
brush.noStroke();
brush.fillBleed(0.3, "out");
brush.fillTexture(0.45, 0.4);
brush.fill(bandCols[i % 3], op);
brush.beginShape(0.35);
brush.vertex(-720, d + randomGaussian(0, 5));
brush.vertex(-260, d - w * 0.4 + randomGaussian(0, 8));
brush.vertex(230, d + randomGaussian(0, 8));
brush.vertex(720, d - randomGaussian(0, 6));
brush.vertex(720, d + w);
brush.vertex(10, d + w + randomGaussian(0, 9));
brush.vertex(-720, d + w * 0.9);
brush.endShape(true);
}
// a few thin strata edge lines
brush.set("2H", "#7fa9b6", 0.85);
for (let i = 0; i < 6; i++) {
const d = random(-420, 460);
brush.line(-650, d, 650, d + randomGaussian(0, 10));
}
pop();
// clean-ice veil — quiet the upper-left to pale ice-blue, not bare paper
brush.noStroke();
brush.fillBleed(0.5, "out");
brush.fillTexture(0.35, 0.3);
brush.fill("#dcebef", 95);
brush.polygon([[-30, -30], [470, -30], [220, 250], [-30, 480]]);
brush.fill("#e6f1f3", 70);
brush.polygon([[-30, -30], [360, -30], [130, 190], [-30, 340]]);
// The large openings diverge without crossing; the left snow shelf stays quiet.
iceFissure([[538, 154], [510, 205], [472, 252], [489, 271], [441, 329],
[398, 382], [416, 400], [367, 469], [323, 527], [292, 572]], 38);
iceFissure([[656, 220], [627, 263], [584, 317], [598, 336], [552, 389],
[522, 437], [537, 453], [490, 516], [458, 575], [427, 620]], 27);
iceFissure([[742, 367], [713, 408], [676, 454], [689, 471], [647, 524],
[610, 580], [622, 598], [582, 650], [554, 686]], 20);
iceFissure([[440, 330], [400, 319], [365, 285], [340, 278]], 8);
iceFissure([[522, 436], [491, 415], [469, 387]], 6);
// snow-grain — spray drifting over the lower and right ice
brush.set("spray", "#f4f8f8", 3.2);
for (let i = 0; i < 9; i++) {
const sx = random(300, 720);
const sy = random(380, 740);
brush.line(sx, sy, sx + random(50, 130), sy + random(30, 90));
}
brush.set("spray", "#cfe4ea", 2.6);
for (let i = 0; i < 5; i++) {
const sx = random(120, 420);
const sy = random(480, 730);
brush.line(sx, sy, sx + random(40, 100), sy + random(20, 70));
}
// one warm rock exposure, shouldering out of a crevasse wall
brush.noStroke();
brush.fillBleed(0.3, "out");
brush.fillTexture(0.6, 0.7);
brush.fill("#a8713f", 150);
brush.polygon([[544, 425], [558, 413], [575, 428], [566, 450], [538, 454]]);
brush.fill("#8a5a30", 120);
brush.polygon([[541, 444], [558, 434], [568, 430], [561, 450], [538, 454]]);
brush.noFill();
brush.set("2B", "#635647", 1.2);
brush.line(539, 453, 561, 450);
brush.line(561, 450, 570, 432);
brush.set("2H", PALETTE[0], 0.9);
brush.line(546, 424, 558, 416);
}