fogón

← NaturalezaObjeto 3Dfogon/roca-con-musgo

Piedra con musgo

de fogonCC09833 bloques
Piedra con musgoArrastrá para girarlo
// «Piedra con musgo» · gpt-6-sol (medium)
// A tall rounded standing stone heavily covered in bright green moss on top and one side, with grey rock showing below.

// A rounded standing stone with a thick, sunlit moss cap and a mossy left side.
const rock = ["#899196", "#9ba3a5", "#aeb6b5", "#c3c9c4"];
const moss = ["#308e43", "#43ad48", "#61c958", "#89dc69"];

function radii(z) {
  let rx;
  if (z < 5) rx = 9.2 + z * 0.18;
  else if (z < 17) rx = 10.1;
  else if (z < 30) rx = 10.1 - (z - 17) * 0.1;
  else if (z < 34) rx = 8.8;
  else rx = 8.8 * Math.sqrt(Math.max(0, 1 - ((z - 34) / 6) ** 2));
  return [rx, rx * 0.88];
}

// Solid, gently leaning stone with an uneven but rounded outline.
for (let z = 0; z <= 39; z++) {
  const [rx, ry] = radii(z);
  const cx = 24 + Math.sin(z * 0.12) * 0.75;
  const cy = 24 + Math.sin(z * 0.16 + 1) * 0.45;
  for (let x = 12; x <= 36; x++) {
    for (let y = 12; y <= 36; y++) {
      const angle = Math.atan2(y - cy, x - cx);
      const uneven = 1 + 0.035 * Math.sin(angle * 5 + z * 0.19)
                       + 0.025 * Math.sin(angle * 9 - z * 0.31);
      const d = ((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2;
      if (d <= uneven * uneven) {
        const shade = rand();
        const color = shade < 0.12 ? rock[0] : shade < 0.72 ? rock[1] : rock[2];
        set(x, y, z, color);
      }
    }
  }
}

function frontStone(x, z, color) {
  for (let y = 12; y <= 29; y++) {
    if (get(x, y, z)) {
      set(x, y, z, color);
      return;
    }
  }
}

// A few short, irregular cracks in the exposed lower face.
[
  [25, 5], [25, 6], [26, 7], [26, 8], [27, 9],
  [26, 12], [27, 13], [27, 14], [28, 15],
  [22, 17], [22, 18], [21, 19], [21, 20]
].forEach(([x, z]) => frontStone(x, z, "#707c80"));

// Recolor only the outside: stone stays visible across the lower front.
const surface = [];
forEach((x, y, z) => {
  const exposed = !get(x + 1, y, z) || !get(x - 1, y, z) ||
                  !get(x, y + 1, z) || !get(x, y - 1, z) ||
                  !get(x, y, z + 1);
  if (exposed) surface.push([x, y, z]);
});

for (const [x, y, z] of surface) {
  const edge = 11 + 2 * Math.sin(y * 0.57 + z * 0.25);
  const leftMoss = x <= 18 && z >= edge;
  const spreadingMoss = x <= 22 && z >= 19 + 2 * Math.sin(x * 0.72 + y * 0.4);
  const frontMoss = y <= 21 && z >= 27 + 2 * Math.sin(x * 0.66);
  const capMoss = z >= 31 + 1.5 * Math.sin(x * 0.43 + y * 0.38);

  if (leftMoss || spreadingMoss || frontMoss || capMoss) {
    const lit = z > 32 || !get(x, y, z + 1);
    const t = rand();
    const color = lit
      ? (t < 0.16 ? moss[1] : t < 0.77 ? moss[2] : moss[3])
      : (t < 0.19 ? moss[0] : t < 0.78 ? moss[1] : moss[2]);
    set(x, y, z, color);

    // Occasional raised tufts give the moss a soft, chunky silhouette.
    if (rand() < 0.13 && z > 8) {
      if (!get(x, y, z + 1) && z < 40) set(x, y, z + 1, moss[2]);
      else if (y < 24 && !get(x, y - 1, z)) set(x, y - 1, z, moss[1]);
      else if (x < 23 && !get(x - 1, y, z)) set(x - 1, y, z, moss[1]);
    }
  } else if (rand() < 0.17) {
    set(x, y, z, z > 18 ? rock[3] : rock[0]);
  }
}

// Small patches of moss trailing down the otherwise bare stone.
for (const [x, z] of [[18, 7], [19, 8], [17, 10], [20, 14], [21, 15]]) {
  for (let y = 12; y <= 29; y++) {
    if (get(x, y, z)) {
      set(x, y, z, moss[1]);
      break;
    }
  }
}