fogón

← Nature3D assetfogon/hongos-marrones

Hongos del bosque

by fogonCC07645 blocks
Hongos del bosqueDrag to turn it
// «Hongos del bosque» · gpt-6-sol (medium)
// A group of brown and tan forest mushrooms with flat caps, growing out of a mossy patch.

const greenDark = "#397d37";
const green = "#55aa45";
const greenLight = "#75c75a";
const greenSun = "#91d66a";

// An uneven, solid mossy patch.
for (let x = 3; x <= 45; x++) {
  for (let y = 6; y <= 42; y++) {
    const dx = (x - 24) / 20;
    const dy = (y - 24) / 17;
    const edge = dx * dx + dy * dy;
    const wobble = (rand() - 0.5) * 0.13;
    if (edge > 1 + wobble) continue;

    const height = edge < 0.72 ? 2 : 1;
    for (let z = 0; z <= height; z++) {
      set(x, y, z, z === height
        ? (rand() < 0.14 ? greenSun : rand() < 0.48 ? greenLight : green)
        : z === 0 ? greenDark : "#478f3d");
    }
    if (edge < 0.8 && rand() < 0.11) {
      set(x, y, height + 1, rand() < 0.5 ? greenLight : greenSun);
    }
  }
}

function mushroom(cx, cy, base, capZ, rx, ry, stemR, colors) {
  const stemTop = capZ + 1;

  // Wide, planted foot and sturdy pale stalk.
  ellipsoid(cx, cy, base + 2, stemR + 1, stemR + 1, 3, colors.foot);
  cylinder(cx, cy, base + 2, stemR, stemTop - base - 1, colors.stem);
  for (let z = base + 3; z <= stemTop; z++) {
    for (let y = cy - stemR; y <= cy + stemR; y++) {
      for (let x = cx - stemR; x <= cx + stemR; x++) {
        if (!get(x, y, z)) continue;
        if ((x - cx) ** 2 + (y - cy) ** 2 > (stemR + 0.4) ** 2) continue;
        if (y <= cy - 1 && rand() < 0.78) set(x, y, z, colors.stemLight);
        else if (x >= cx + stemR - 1 && rand() < 0.6) set(x, y, z, colors.stemShade);
      }
    }
  }

  // A shallow, broad cap: dark rolled edge, nearly level sunlit top.
  for (let x = cx - rx; x <= cx + rx; x++) {
    for (let y = cy - ry; y <= cy + ry; y++) {
      const d = ((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2;
      if (d > 1) continue;

      const top = capZ + (d < 0.76 ? 4 : d < 0.94 ? 3 : 2);
      for (let z = capZ; z <= top; z++) {
        let color;
        if (z === capZ || d > 0.88) color = colors.rim;
        else if (z === top) color = rand() < 0.12 ? colors.highlight : colors.top;
        else color = colors.side;
        set(x, y, z, color);
      }
    }
  }

  // Pale underside and short radial gills, visible beneath the overhang.
  for (let x = cx - rx + 1; x < cx + rx; x++) {
    for (let y = cy - ry + 1; y < cy + ry; y++) {
      const d = ((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2;
      if (d > 0.23 && d < 0.75) set(x, y, capZ - 1, colors.gills);
    }
  }
  for (let a = 0; a < Math.PI * 2; a += Math.PI / 9) {
    line(
      cx + Math.cos(a) * (stemR + 1), cy + Math.sin(a) * (stemR + 1), capZ - 1,
      cx + Math.cos(a) * (rx - 2), cy + Math.sin(a) * (ry - 2), capZ - 1,
      0, colors.gillShade
    );
  }

  // A few broad, irregular cream flecks on the flat upper surface.
  const flecks = Math.max(4, Math.round(rx * ry / 9));
  for (let i = 0; i < flecks; i++) {
    const a = rand() * Math.PI * 2;
    const r = 0.24 + rand() * 0.54;
    const x = Math.round(cx + Math.cos(a) * rx * r);
    const y = Math.round(cy + Math.sin(a) * ry * r);
    const d = ((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2;
    const z = capZ + (d < 0.76 ? 4 : 3);
    set(x, y, z + 1, rand() < 0.65 ? colors.fleck : colors.highlight);
    if (rand() < 0.32) set(x + 1, y, z + 1, colors.fleck);
  }
}

mushroom(21, 29, 2, 24, 10, 8, 3, {
  foot: "#a88a64", stem: "#d7bb8d", stemLight: "#f1dbaa",
  stemShade: "#ac8d68", rim: "#593625", side: "#865133",
  top: "#aa7040", highlight: "#c68a50", fleck: "#e5ba78",
  gills: "#d2ae7d", gillShade: "#aa8059"
});
mushroom(35, 19, 2, 17, 7, 6, 2, {
  foot: "#af8b61", stem: "#e0bf8c", stemLight: "#f5dcaa",
  stemShade: "#af8c63", rim: "#754329", side: "#ae6836",
  top: "#cf8d43", highlight: "#e9ab58", fleck: "#ffe0a0",
  gills: "#e4bb83", gillShade: "#b58b5e"
});
mushroom(10, 18, 2, 14, 6, 5, 2, {
  foot: "#aa8867", stem: "#d9ba91", stemLight: "#f0d9af",
  stemShade: "#ad8b6d", rim: "#684032", side: "#a35e3e",
  top: "#bc794b", highlight: "#d99662", fleck: "#f4cb94",
  gills: "#ddba91", gillShade: "#b78c69"
});
mushroom(38, 34, 2, 12, 5, 4, 2, {
  foot: "#a8906c", stem: "#d9c59b", stemLight: "#f0dfb4",
  stemShade: "#ae9975", rim: "#68462c", side: "#9c6a3a",
  top: "#bc894d", highlight: "#d9a45f", fleck: "#f5d49a",
  gills: "#e0c393", gillShade: "#b19467"
});
mushroom(23, 10, 2, 9, 4, 4, 1, {
  foot: "#ae9470", stem: "#e0cda4", stemLight: "#f3e2bc",
  stemShade: "#b5a07e", rim: "#80532e", side: "#b77b40",
  top: "#d69c55", highlight: "#ecb86e", fleck: "#ffe0a3",
  gills: "#e4ca9c", gillShade: "#b9976d"
});

// Little moss pillows, grass tufts, and cheerful woodland flowers.
for (const [x, y, r] of [
  [7, 27, 2], [15, 9, 2], [29, 38, 3],
  [41, 25, 2], [13, 35, 2], [31, 8, 2]
]) {
  ellipsoid(x, y, 2, r, r, 2, greenLight);
  set(x, y, 4, greenSun);
}

for (let i = 0; i < 85; i++) {
  const x = 5 + Math.floor(rand() * 39);
  const y = 8 + Math.floor(rand() * 33);
  if (!get(x, y, 1) || get(x, y, 5)) continue;
  const z = get(x, y, 3) ? 4 : 3;
  set(x, y, z, rand() < 0.5 ? "#7ccc52" : "#4da744");
  if (rand() < 0.35) set(x, y, z + 1, "#94dc65");
}

for (const [x, y, petal] of [
  [8, 11, "#fff2cd"], [40, 13, "#ffe6ee"],
  [7, 32, "#ffe3a0"], [34, 39, "#f9d8ff"],
  [17, 40, "#fff0be"], [29, 13, "#ffffff"]
]) {
  if (!get(x, y, 1)) continue;
  box(x, y, 3, x, y, 5, "#4f9b42");
  set(x - 1, y, 5, petal);
  set(x + 1, y, 5, petal);
  set(x, y - 1, 5, petal);
  set(x, y + 1, 5, petal);
  set(x, y, 5, "#f5ae3e");
}