Primordial Alchemy - The Emergence

📅 April 25, 2026 🏷️ art
reaction-diffusion alchemy primordial metallic-gold occult emergence sacred-geometry life-cycles pending-review
Generated by GridFlow AI | Tags: reaction-diffusion, alchemy, primordial, metallic-gold, occult, emergence, sacred-geometry, life-cycles

💡 AI 提示词

Spontaneous Emergence of Life from Primordial Chemistry - esoteric occult visualization with metallic gold and brass structures floating in infinite dark voids, reaction-diffusion simulating cellular life-and-death cycles with aggressive mutation, sacred geometry, psychedelic illusions

🔧 核心算法要点

  1. Gray-Scott reaction-diffusion with spatially-varying feed/kill rates controlled by Perlin noise for organic pattern emergence
  2. Pixel-level rendering using loadPixels/updatePixels with 3-pixel stepping for performance while maintaining visual fidelity
  3. Multi-layer compositing with 5 separate p.createGraphics buffers: background, reaction, structure, glow, and accent layers
  4. Aggressive mutation via noise-driven parameter variation creating non-equilibrium patterns that evolve chaotically
  5. Sacred geometry overlay including Flower of Life, golden spirals, and concentric rings rendered with additive blend modes
  6. Mouse-reactive chemical injection creating localized bursts of B chemical that trigger new pattern nucleation

🎨 原始代码

var sketch = function(p) {
  var config = {
    gridScale: 3,
    rdWidth: 0,
    rdHeight: 0,
    baseFeed: 0.058,
    baseKill: 0.065,
    diffusionA: 0.9,
    diffusionB: 0.4,
    dt: 1.0,
    mutationStrength: 0.015
  };

  var chemicalA, chemicalB, nextA, nextB;
  var backgroundBuffer, reactionBuffer, structureBuffer, glowBuffer, accentBuffer;
  var time = 0;
  var mouseInfluence = { x: 0, y: 0, active: false, strength: 0 };
  var interactionMode = 0;
  var spiralAngle = 0;
  var noiseSeed = 0;

  var GOLD = {
    deepVoid: [5, 5, 7],
    void: [10, 10, 15],
    brightGold: [255, 223, 128],
    gold: [212, 175, 55],
    antiqueGold: [184, 155, 76],
    darkGold: [139, 107, 55],
    bronze: [139, 90, 43],
    copper: [184, 115, 51],
    deepBronze: [124, 74, 39]
  };

  p.setup = function() {
    var container = document.getElementById('p5-wrapper');
    var w = container.offsetWidth;
    var h = container.offsetHeight;

    p.createCanvas(w, h).parent(container);
    p.colorMode(p.RGB, 255, 255, 255, 255);
    p.noStroke();

    config.rdWidth = Math.floor(w / config.gridScale);
    config.rdHeight = Math.floor(h / config.gridScale);

    chemicalA = new Float32Array(config.rdWidth * config.rdHeight);
    chemicalB = new Float32Array(config.rdWidth * config.rdHeight);
    nextA = new Float32Array(config.rdWidth * config.rdHeight);
    nextB = new Float32Array(config.rdWidth * config.rdHeight);

    backgroundBuffer = p.createGraphics(w, h);
    reactionBuffer = p.createGraphics(w, h);
    structureBuffer = p.createGraphics(w, h);
    glowBuffer = p.createGraphics(w, h);
    accentBuffer = p.createGraphics(w, h);

    noiseSeed = p.random(10000);
    initializeChemicals();
    renderStaticStructure();
  };

  function initializeChemicals() {
    for (var i = 0; i < chemicalA.length; i++) {
      chemicalA[i] = 1;
      chemicalB[i] = 0;
    }

    var seedPatterns = [
      { count: 8, radiusMin: 3, radiusMax: 12, cx: 0.5, cy: 0.5, spread: 0.15 },
      { count: 12, radiusMin: 2, radiusMax: 8, cx: 0.3, cy: 0.7, spread: 0.2 },
      { count: 6, radiusMin: 4, radiusMax: 15, cx: 0.7, cy: 0.3, spread: 0.25 }
    ];

    for (var s = 0; s < seedPatterns.length; s++) {
      var pattern = seedPatterns[s];
      for (var i = 0; i < pattern.count; i++) {
        var angle = (i / pattern.count) * p.TWO_PI + p.random(-0.3, 0.3);
        var dist = p.random(0, pattern.spread);
        var cx = Math.floor((pattern.cx + p.cos(angle) * dist) * config.rdWidth);
        var cy = Math.floor((pattern.cy + p.sin(angle) * dist) * config.rdHeight);
        var radius = pattern.radiusMin + Math.floor(p.random(pattern.radiusMax - pattern.radiusMin));

        seedCircle(cx, cy, radius);
      }
    }
  }

  function seedCircle(cx, cy, radius) {
    for (var dy = -radius; dy <= radius; dy++) {
      for (var dx = -radius; dx <= radius; dx++) {
        var dist = Math.sqrt(dx * dx + dy * dy);
        if (dist < radius) {
          var nx = cx + dx;
          var ny = cy + dy;
          if (nx >= 0 && nx < config.rdWidth && ny >= 0 && ny < config.rdHeight) {
            var idx = ny * config.rdWidth + nx;
            var falloff = 1 - (dist / radius);
            chemicalB[idx] = Math.max(chemicalB[idx], falloff * 0.9);
            chemicalA[idx] = 1 - chemicalB[idx];
          }
        }
      }
    }
  }

  function renderStaticStructure() {
    var w = p.width;
    var h = p.height;
    var cx = w / 2;
    var cy = h / 2;

    structureBuffer.clear();
    structureBuffer.noStroke();

    structureBuffer.fill(15, 12, 8, 180);
    for (var i = 0; i < 7; i++) {
      var offset = (i - 3) * 40;
      structureBuffer.ellipse(cx + offset * 0.3, cy + offset, w * 0.6 - i * 30, 120 + i * 20);
    }

    accentBuffer.clear();
    accentBuffer.noStroke();

    for (var i = 0; i < 3; i++) {
      var r = 180 + i * 60;
      var alpha = 15 + i * 5;
      accentBuffer.fill(139, 107, 55, alpha);
      accentBuffer.ellipse(cx, cy, r * 2, r * 0.4);
      accentBuffer.fill(184, 155, 76, alpha * 0.5);
      accentBuffer.ellipse(cx, cy - 5, r * 1.8, r * 0.35);
    }
  }

  function stepReactionDiffusion() {
    var w = config.rdWidth;
    var h = config.rdHeight;
    var scale = config.gridScale;

    for (var y = 1; y < h - 1; y++) {
      for (var x = 1; x < w - 1; x++) {
        var idx = y * w + x;

        var a = chemicalA[idx];
        var b = chemicalB[idx];

        var aLap = chemicalA[idx - 1] + chemicalA[idx + 1] + chemicalA[idx - w] + chemicalA[idx + w] - 4 * a;
        var bLap = chemicalB[idx - 1] + chemicalB[idx + 1] + chemicalB[idx - w] + chemicalB[idx + w] - 4 * b;

        var spaceNoise = p.noise(x * 0.008, y * 0.008, time * 0.02) - 0.5;
        var mutation = spaceNoise * config.mutationStrength * 2;

        var feed = config.baseFeed + mutation * 0.5;
        var kill = config.baseKill + mutation;

        var reaction = a * b * b;
        var da = config.diffusionA * aLap - reaction + feed * (1 - a);
        var db = config.diffusionB * bLap + reaction - (kill + feed) * b;

        if (mouseInfluence.active) {
          var mx = Math.floor(mouseInfluence.x / scale);
          var my = Math.floor(mouseInfluence.y / scale);
          var dx = x - mx;
          var dy = y - my;
          var dist = Math.sqrt(dx * dx + dy * dy);
          var radius = 25;

          if (dist < radius) {
            var influence = (1 - dist / radius) * mouseInfluence.strength * 0.4;
            db += influence * 2;
            da -= influence * 0.5;
          }
        }

        nextA[idx] = Math.max(0, Math.min(1, a + da * config.dt));
        nextB[idx] = Math.max(0, Math.min(1, b + db * config.dt));
      }
    }

    var temp = chemicalA;
    chemicalA = nextA;
    nextA = temp;
    temp = chemicalB;
    chemicalB = nextB;
    nextB = temp;
  }

  function renderReactionBuffer() {
    var w = config.rdWidth;
    var h = config.rdHeight;
    var scale = config.gridScale;
    var canvasW = p.width;

    reactionBuffer.loadPixels();
    var pixels = reactionBuffer.pixels;

    for (var y = 0; y < h; y++) {
      for (var x = 0; x < w; x++) {
        var idx = y * w + x;
        var a = chemicalA[idx];
        var b = chemicalB[idx];
        var t = b - a;

        var cr, cg, cb;

        if (t < -0.3) {
          var localT = (t + 1) / 0.7;
          cr = p.lerp(5, 20, localT);
          cg = p.lerp(5, 15, localT);
          cb = p.lerp(7, 25, localT);
        } else if (t < 0) {
          var localT = (t + 0.3) / 0.3;
          cr = p.lerp(20, 124, localT);
          cg = p.lerp(15, 74, localT);
          cb = p.lerp(25, 39, localT);
        } else if (t < 0.3) {
          var localT = t / 0.3;
          cr = p.lerp(124, 212, localT);
          cg = p.lerp(74, 175, localT);
          cb = p.lerp(39, 55, localT);
        } else {
          var localT = Math.min(1, (t - 0.3) / 0.4);
          cr = p.lerp(212, 255, localT);
          cg = p.lerp(175, 223, localT);
          cb = p.lerp(55, 128, localT);
        }

        var px = x * scale;
        var py = y * scale;

        for (var py2 = 0; py2 < scale; py2++) {
          for (var px2 = 0; px2 < scale; px2++) {
            var pixelIdx = ((py + py2) * canvasW + (px + px2)) * 4;
            pixels[pixelIdx] = cr;
            pixels[pixelIdx + 1] = cg;
            pixels[pixelIdx + 2] = cb;
            pixels[pixelIdx + 3] = 255;
          }
        }
      }
    }

    reactionBuffer.updatePixels();
  }

  function renderGlowBuffer() {
    var w = p.width;
    var h = p.height;
    var cx = w / 2;
    var cy = h / 2;

    glowBuffer.clear();
    glowBuffer.blendMode(p.ADD);

    for (var i = 0; i < 60; i++) {
      var angle = spiralAngle + (i / 60) * p.TWO_PI * 3;
      var radius = 30 + i * 4 + p.noise(i * 0.3, time * 0.5) * 30;
      var gx = cx + p.cos(angle) * radius;
      var gy = cy + p.sin(angle) * radius * 0.6;
      var brightness = p.noise(i * 0.5 + time, noiseSeed) * 0.8 + 0.2;
      var size = 3 + brightness * 8;

      var colorMix = (i % 20) / 20;
      var r = p.lerp(212, 255, colorMix);
      var g = p.lerp(175, 223, colorMix);
      var b = p.lerp(55, 128, colorMix);

      glowBuffer.fill(r * brightness, g * brightness, b * brightness, 60);
      glowBuffer.ellipse(gx, gy, size, size * 0.6);
    }

    glowBuffer.fill(255, 240, 180, 40);
    glowBuffer.ellipse(cx, cy, 200 + p.sin(time * 0.3) * 30, 100 + p.cos(time * 0.2) * 15);

    glowBuffer.fill(212, 175, 55, 20);
    glowBuffer.ellipse(cx, cy, 350, 180);

    glowBuffer.blendMode(p.BLEND);
  }

  function drawBackground() {
    backgroundBuffer.background(5, 5, 7);

    var w = p.width;
    var h = p.height;
    var cx = w / 2;
    var cy = h / 2;

    for (var i = 0; i < 200; i++) {
      var nx = p.noise(i * 0.1, noiseSeed, time * 0.1) - 0.5;
      var ny = p.noise(i * 0.1, noiseSeed + 100, time * 0.1) - 0.5;
      var brightness = p.noise(i * 0.2 + time * 0.05, noiseSeed) * 40 + 10;
      backgroundBuffer.fill(brightness * 0.8, brightness * 0.7, brightness * 0.4, 100);
      backgroundBuffer.ellipse(cx + nx * w, cy + ny * h, 2, 2);
    }

    for (var r = Math.max(w, h); r > 50; r -= 80) {
      var alpha = p.map(r, 50, Math.max(w, h), 8, 2);
      backgroundBuffer.noFill();
      backgroundBuffer.stroke(20, 18, 12, alpha);
      backgroundBuffer.strokeWeight(1);
      backgroundBuffer.ellipse(cx, cy, r, r * 0.9);
    }
    backgroundBuffer.noStroke();
  }

  function drawSacredGeometry() {
    var w = p.width;
    var h = p.height;
    var cx = w / 2;
    var cy = h / 2;

    structureBuffer.blendMode(p.ADD);

    for (var ring = 0; ring < 5; ring++) {
      var baseRadius = 60 + ring * 70;
      var petals = 6 + ring * 2;
      var alpha = 25 - ring * 4;

      structureBuffer.stroke(184, 155, 76, alpha);
      structureBuffer.strokeWeight(1.5 - ring * 0.2);
      structureBuffer.noFill();

      for (var i = 0; i < petals; i++) {
        var angle = (i / petals) * p.TWO_PI + time * 0.02 * (ring % 2 === 0 ? 1 : -1);
        var px = cx + p.cos(angle) * baseRadius;
        var py = cy + p.sin(angle) * baseRadius;

        structureBuffer.ellipse(px, py, 50 + ring * 15, 50 + ring * 15);
      }
    }

    var spirals = 2;
    for (var s = 0; s < spirals; s++) {
      var dir = s === 0 ? 1 : -1;
      structureBuffer.stroke(212, 175, 55, 35);
      structureBuffer.strokeWeight(1);
      structureBuffer.noFill();

      structureBuffer.beginShape();
      for (var i = 0; i < 150; i++) {
        var t = i / 150;
        var angle = t * p.TWO_PI * 4 * dir + s * p.PI;
        var radius = 20 + t * 300;
        var x = cx + p.cos(angle) * radius;
        var y = cy + p.sin(angle) * radius * 0.7;
        structureBuffer.curveVertex(x, y);
      }
      structureBuffer.endShape();
    }

    structureBuffer.blendMode(p.BLEND);

    accentBuffer.blendMode(p.ADD);
    for (var i = 0; i < 5; i++) {
      var offset = (i - 2) * 25;
      var alpha = 30 - Math.abs(i - 2) * 8;
      accentBuffer.fill(255, 220, 140, alpha);
      accentBuffer.ellipse(cx, cy + offset * 0.5, 400 - Math.abs(offset) * 3, 80 - Math.abs(offset));
    }
    accentBuffer.blendMode(p.BLEND);
  }

  p.draw = function() {
    time += 0.008;
    spiralAngle += 0.015;

    if (mouseInfluence.active) {
      mouseInfluence.strength *= 0.98;
    }

    stepReactionDiffusion();
    renderReactionBuffer();
    renderGlowBuffer();
    drawBackground();

    p.image(backgroundBuffer, 0, 0);

    if (interactionMode === 0) {
      p.blendMode(p.ADD);
      p.image(glowBuffer, 0, 0);
      p.blendMode(p.BLEND);
    }

    p.image(structureBuffer, 0, 0);
    p.image(reactionBuffer, 0, 0);
    p.image(accentBuffer, 0, 0);

    drawSacredGeometry();

    if (mouseInfluence.active) {
      var mx = mouseInfluence.x;
      var my = mouseInfluence.y;
      var r = 80;

      for (var i = 0; i < 12; i++) {
        var angle = (i / 12) * p.TWO_PI + time * 3;
        var px = mx + p.cos(angle) * r;
        var py = my + p.sin(angle) * r;
        var size = 4 + p.sin(time * 5 + i) * 2;

        p.fill(255, 240, 180, 150);
        p.ellipse(px, py, size, size * 0.7);
      }

      p.noFill();
      p.stroke(212, 175, 55, 50);
      p.strokeWeight(1);
      p.ellipse(mx, my, r * 2, r * 2 * 0.7);
      p.noStroke();
    }
  };

  p.mouseMoved = function() {
    mouseInfluence.x = p.mouseX;
    mouseInfluence.y = p.mouseY;
    mouseInfluence.active = true;
    mouseInfluence.strength = Math.min(mouseInfluence.strength + 0.1, 1);
  };

  p.mousePressed = function() {
    mouseInfluence.x = p.mouseX;
    mouseInfluence.y = p.mouseY;
    mouseInfluence.active = true;
    mouseInfluence.strength = 1.5;

    var gridX = Math.floor(p.mouseX / config.gridScale);
    var gridY = Math.floor(p.mouseY / config.gridScale);
    var seedRadius = 8 + Math.floor(p.random(8));

    for (var dy = -seedRadius; dy <= seedRadius; dy++) {
      for (var dx = -seedRadius; dx <= seedRadius; dx++) {
        var dist = Math.sqrt(dx * dx + dy * dy);
        if (dist < seedRadius) {
          var nx = gridX + dx;
          var ny = gridY + dy;
          if (nx >= 0 && nx < config.rdWidth && ny >= 0 && ny < config.rdHeight) {
            var idx = ny * config.rdWidth + nx;
            var falloff = Math.pow(1 - dist / seedRadius, 2);
            chemicalB[idx] = Math.max(chemicalB[idx], falloff);
            chemicalA[idx] = 1 - chemicalB[idx];
          }
        }
      }
    }
  };

  p.mouseReleased = function() {
    mouseInfluence.active = false;
  };

  p.keyPressed = function() {
    var key = p.key.toLowerCase();

    if (key === 'r') {
      initializeChemicals();
    } else if (key === 'm') {
      interactionMode = (interactionMode + 1) % 2;
    } else if (key === 'g') {
      config.mutationStrength = (config.mutationStrength === 0.015) ? 0.05 : 0.015;
    } else if (key === 's') {
      config.gridScale = (config.gridScale === 3) ? 1 : 3;
      config.rdWidth = Math.floor(p.width / config.gridScale);
      config.rdHeight = Math.floor(p.height / config.gridScale);
      chemicalA = new Float32Array(config.rdWidth * config.rdHeight);
      chemicalB = new Float32Array(config.rdWidth * config.rdHeight);
      nextA = new Float32Array(config.rdWidth * config.rdHeight);
      nextB = new Float32Array(config.rdWidth * config.rdHeight);
      initializeChemicals();
    }

    return false;
  };

  p.windowResized = function() {
    var container = document.getElementById('p5-wrapper');
    var w = container.offsetWidth;
    var h = container.offsetHeight;

    p.resizeCanvas(w, h);

    backgroundBuffer.resizeCanvas(w, h);
    reactionBuffer.resizeCanvas(w, h);
    structureBuffer.resizeCanvas(w, h);
    glowBuffer.resizeCanvas(w, h);
    accentBuffer.resizeCanvas(w, h);

    renderStaticStructure();
  };
};
// p5 init stripped

✨ AI 艺术解读

This artwork simulates the spontaneous emergence of complex ordered structures from primordial chemical chaos using reaction-diffusion dynamics. The metallic gold and bronze palette evokes alchemical transmutation - the ancient pursuit of creating life from base matter. Sacred geometry overlays suggest cosmic order underlying apparent randomness, while aggressive parameter mutation represents the evolutionary pressure that drives self-organization. The piece invites contemplation on how consciousness and life might emerge from pure mathematics interacting with matter.

📝 补充说明

  • Use gridScale of 3 for real-time performance; press 's' to toggle to 1 for high-quality static renders
  • Press 'g' to increase mutation strength for more chaotic pattern evolution
  • Press 'm' to toggle between glow-dominant and structure-dominant visual modes
  • Click to inject new chemical seeds that trigger emergent pattern growth near the cursor