fogón

← Fantasy3D assetfogon/orbe-magico

Orbe mágico

by fogonCC016267 blocks
Orbe mágicoDrag to turn it
// «Orbe mágico» · gpt-6-sol (medium)
// A large glowing crystal ball orb floating above an ornate pedestal: the pedestal is a dark wood and gold stand with three curled claw feet holding a gold ring cradle. The orb is a big sphere with swirling cyan, violet and white light inside, brighter at the center.

const wood = "#38283e", woodLight = "#594052", woodDark = "#281e34";
const gold = "#dba74f", goldLight = "#ffe098", goldDark = "#90643e";
const cx = 24, cy = 24;

// Three broad, curled wooden claw feet.
for (const angle of [-Math.PI / 2, Math.PI / 6, 5 * Math.PI / 6]) {
  const dx = Math.cos(angle), dy = Math.sin(angle);
  line(cx + dx * 3, cy + dy * 3, 5,
       cx + dx * 14, cy + dy * 14, 2, 3, woodDark);
  line(cx + dx * 5, cy + dy * 5, 6,
       cx + dx * 15, cy + dy * 15, 3, 2, woodLight);
  line(cx + dx * 14, cy + dy * 14, 2,
       cx + dx * 18, cy + dy * 18, 1, 2, wood);
  // The tips curl up, ending in polished golden claws.
  line(cx + dx * 18, cy + dy * 18, 1,
       cx + dx * 19, cy + dy * 19, 5, 1, gold);
  sphere(cx + dx * 19, cy + dy * 19, 5, 1.5, goldLight);
  sphere(cx + dx * 13, cy + dy * 13, 3, 1, goldDark);
}

// A squat, carved wooden pedestal with brass collars.
cylinder(cx, cy, 2, 6, 4, woodDark);
cylinder(cx, cy, 3, 5, 4, woodLight);
cylinder(cx, cy, 6, 4, 9, wood);
cylinder(cx, cy, 7, 3, 7, woodLight);
for (const [z, r, h, color] of [
  [4, 6, 1, goldDark], [5, 6, 1, gold],
  [9, 4, 1, goldDark], [13, 5, 1, gold],
  [15, 7, 2, woodDark], [16, 8, 1, gold]
]) cylinder(cx, cy, z, r, h, color);

for (let a = 0; a < 8; a++) {
  const t = a * Math.PI / 4;
  line(cx + 4 * Math.cos(t), cy + 4 * Math.sin(t), 7,
       cx + 4 * Math.cos(t), cy + 4 * Math.sin(t), 13,
       0, a % 2 ? goldDark : gold);
}
sphere(cx, 17, 10, 1.5, goldLight);

// Chunky, engraved gold ring cradle beneath the floating orb.
for (let i = 0; i < 144; i++) {
  const a = i * Math.PI * 2 / 144;
  const x = cx + 11.5 * Math.cos(a);
  const y = cy + 11.5 * Math.sin(a);
  sphere(x, y, 18, 1.7, i % 12 < 3 ? goldLight : gold);
  if (i % 12 === 0) sphere(x, y, 20, 1.2, goldLight);
}
for (const a of [-Math.PI / 2, Math.PI / 6, 5 * Math.PI / 6]) {
  const x = cx + 11.5 * Math.cos(a), y = cy + 11.5 * Math.sin(a);
  line(x, y, 18, x + 2 * Math.cos(a), y + 2 * Math.sin(a), 23, 1, gold);
  sphere(x + 2 * Math.cos(a), y + 2 * Math.sin(a), 23, 1.2, goldLight);
}

// The entire luminous sphere floats as one moving part.
part("orb", [cx, cy, 31]);
const R = 14.5;
const shades = [
  "#345ab0", "#476bc2", "#624cc0", "#8761da",
  "#2aa8cf", "#51cee7", "#84eeef", "#c2fcff"
];

for (let x = 9; x <= 39; x++)
for (let y = 9; y <= 39; y++)
for (let z = 16; z <= 46; z++) {
  const dx = x - cx, dy = y - cy, dz = z - 31;
  const d2 = dx * dx + dy * dy + dz * dz;
  if (d2 > R * R) continue;

  const screenR = Math.hypot(dx, dz);
  const wave = Math.sin(Math.atan2(dz, dx) * 3 + screenR * 0.75 + dy * 0.22);
  let color;
  if (dy < 1 && screenR < 4.4) {
    color = screenR < 2.6 ? "#eaffff" : "#aafaff";
  } else if (wave > 0.48 && dy < 3) {
    color = rand() < 0.35 ? shades[7] : shades[5];
  } else if (dy < 0 && screenR < 9 && rand() < 0.18) {
    color = shades[6];
  } else {
    color = shades[Math.min(5, Math.max(0,
      Math.floor(2.1 + wave * 1.7 + (z - 31) * 0.07 + rand() * 1.4)))];
  }
  set(x, y, z, color);
}

// Sweeping, bright curls drawn across the viewer-facing hemisphere.
for (const offset of [0, Math.PI * 0.88, Math.PI * 1.65]) {
  for (let i = 0; i < 115; i++) {
    const t = i / 114;
    const radius = 2.5 + 9.2 * t;
    const a = offset + 4.8 * t;
    const x = cx + radius * Math.cos(a);
    const z = 31 + radius * Math.sin(a);
    const y = cy - Math.sqrt(Math.max(0, R * R - radius * radius)) - 0.25;
    sphere(x, y, z, t < 0.3 ? 1 : 0.65,
           i % 9 < 3 ? "#f2ffff" : t > 0.7 ? "#a579ff" : "#7cf7ff");
  }
}

// Star-like heart and scattered pinpricks of magic.
sphere(cx, cy - 14, 31, 2.4, "#dfffff");
sphere(cx, cy - 16, 31, 1.1, "#ffffff");
for (let i = 0; i < 35; i++) {
  const x = cx + (rand() - 0.5) * 25;
  const z = 31 + (rand() - 0.5) * 25;
  const q = (x - cx) ** 2 + (z - 31) ** 2;
  if (q > 185 || q < 18) continue;
  const y = cy - Math.sqrt(R * R - q);
  sphere(x, y - 0.5, z, rand() < 0.25 ? 1 : 0.55,
         rand() < 0.5 ? "#ffffff" : "#a4fbff");
}

animate("orb", { type: "bob", axis: "z", speed: 1.2, amplitude: 1.5 });
animate("orb", {
  type: "colors", axis: "z", speed: 0.8, amplitude: 0.2,
  palette: ["#53edff", "#a66bff", "#ffffff", "#487dff"],
  pattern: "noise", glow: 1
});