Ego-Death Fractal Zoom
Generated by GridFlow AI | Tags: fractal, julia-set, ego-death, mathematical-existence, hallucinatory, complex-numbers, recursive, monochrome
💡 AI 提示词
Ego-Death Fractal Zoom Into the Boundaries of Mathematical Existence — hallucinatory monochrome with single hue, ethereal bloom, deep shadows, complex number mapping, Julia set per-pixel rendering, recursive void structures, sacred geometry, psychedelic illusions, esoteric cryptography, multi-layer compositing, advanced blend modes, recursive mathematical functions, cosmic vastness, non-euclidean physics simulation🔧 核心算法要点
- Julia set computation per-pixel using complex number iteration (z = z^2 + c) with escape time algorithm and smooth iteration count for anti-aliased boundaries
- Per-pixel rendering with loadPixels()/updatePixels() for direct manipulation of fractal brightness values and color mapping
- Multi-layer compositing using createGraphics() offscreen buffers for base fractal, bloom layer, and atmospheric overlay
- Bloom effect applied through iterative Gaussian-like blur passes on pixel data, creating ethereal glow from bright fractal regions
- Dynamic mouse influence on Julia set parameter 'c' creating real-time morphing between fractal states based on cursor position
- Recursive zoom and pan system with smooth interpolation toward target parameters, simulating infinite descent into mathematical void
🎨 原始代码
var sketch = function(p) {
var juliaBuffer;
var glowBuffer;
var maskBuffer;
var cReal, cImag;
var zoom = 1.0;
var targetZoom = 1.0;
var panX = 0, panY = 0;
var targetPanX = 0, targetPanY = 0;
var bloomPasses = 3;
var time = 0;
var mode = 0;
var maxIterations = 128;
var pixelStep = 2;
var container;
p.setup = function() {
container = document.getElementById('p5-wrapper');
var w = container.offsetWidth;
var h = container.offsetHeight;
var cnv = p.createCanvas(w, h).parent(container);
juliaBuffer = p.createGraphics(w, h);
juliaBuffer.noStroke();
glowBuffer = p.createGraphics(w, h);
glowBuffer.noStroke();
maskBuffer = p.createGraphics(w, h);
maskBuffer.noStroke();
p.pixelDensity(1);
p.colorMode(p.HSB, 360, 100, 100, 100);
resetFractal();
};
function resetFractal() {
cReal = p.random(-1.5, 1.5);
cImag = p.random(-1.5, 1.5);
zoom = 1.0;
targetZoom = 1.0;
panX = 0;
panY = 0;
targetPanX = 0;
targetPanY = 0;
time = 0;
}
p.draw = function() {
time += 0.01;
zoom += (targetZoom - zoom) * 0.05;
panX += (targetPanX - panX) * 0.05;
panY += (targetPanY - panY) * 0.05;
renderJuliaFractal();
applyBloomEffect();
compositeLayers();
p.image(juliaBuffer, 0, 0);
renderOverlayEffects();
}
function renderJuliaFractal() {
juliaBuffer.loadPixels();
var w = p.width;
var h = p.height;
var centerX = w / 2;
var centerY = h / 2;
var scale = 4.0 / zoom;
var aspectRatio = w / h;
var mouseInfluence = 0.3;
var dynamicCReal = cReal + (p.mouseX / w - 0.5) * mouseInfluence * (p.sin(time) * 0.5 + 0.5);
var dynamicCImag = cImag + (p.mouseY / h - 0.5) * mouseInfluence * (p.cos(time * 0.7) * 0.5 + 0.5);
for (var py = 0; py < h; py += pixelStep) {
for (var px = 0; px < w; px += pixelStep) {
var x0 = (px - centerX) / centerX * scale + panX;
var y0 = (py - centerY) / centerY * scale / aspectRatio + panY;
var x = x0;
var y = y0;
var iteration = 0;
var smoothValue = 0;
while (iteration < maxIterations) {
var x2 = x * x;
var y2 = y * y;
if (x2 + y2 > 256) {
var log_zn = Math.log(x2 + y2) / 2;
var nu = Math.log(log_zn / Math.log(2)) / Math.log(2);
smoothValue = iteration + 1 - nu;
break;
}
var temp = x2 - y2 + dynamicCReal;
y = 2 * x * y + dynamicCImag;
x = temp;
iteration++;
}
var brightness = 0;
var hue = 260;
if (iteration < maxIterations) {
brightness = p.map(smoothValue, 0, maxIterations, 0, 100);
brightness = Math.pow(brightness / 100, 0.5) * 100;
var depthFactor = iteration / maxIterations;
hue = 260 + depthFactor * 40;
}
var alpha = brightness * 0.8;
for (var dy = 0; dy < pixelStep && py + dy < h; dy++) {
for (var dx = 0; dx < pixelStep && px + dx < w; dx++) {
var idx = ((py + dy) * w + (px + dx)) * 4;
juliaBuffer.pixels[idx] = hue;
juliaBuffer.pixels[idx + 1] = 80;
juliaBuffer.pixels[idx + 2] = brightness;
juliaBuffer.pixels[idx + 3] = alpha;
}
}
}
}
juliaBuffer.updatePixels();
}
function applyBloomEffect() {
glowBuffer.background(0, 0, 0, 0);
glowBuffer.image(juliaBuffer, 0, 0);
glowBuffer.loadPixels();
var w = p.width;
var h = p.height;
var bloomStrength = 15;
for (var pass = 0; pass < bloomPasses; pass++) {
var tempBuffer = p.createGraphics(w, h);
tempBuffer.loadPixels();
for (var y = 0; y < h; y += pixelStep) {
for (var x = 0; x < w; x += pixelStep) {
var idx = (y * w + x) * 4;
var centerBright = glowBuffer.pixels[idx + 3];
var sumR = 0, sumG = 0, sumB = 0, sumA = 0;
var count = 0;
var radius = bloomStrength * (pass + 1);
for (var dy = -radius; dy <= radius; dy += pixelStep) {
for (var dx = -radius; dx <= radius; dx += pixelStep) {
var nx = x + dx;
var ny = y + dy;
if (nx >= 0 && nx < w && ny >= 0 && ny < h) {
var nidx = (ny * w + nx) * 4;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist <= radius) {
var weight = 1 - dist / radius;
sumR += glowBuffer.pixels[nidx] * weight;
sumG += glowBuffer.pixels[nidx + 1] * weight;
sumB += glowBuffer.pixels[nidx + 2] * weight;
sumA += glowBuffer.pixels[nidx + 3] * weight;
count++;
}
}
}
}
if (count > 0) {
var blendRatio = 0.3 / (pass + 1);
tempBuffer.pixels[idx] = glowBuffer.pixels[idx] * (1 - blendRatio) + (sumR / count) * blendRatio;
tempBuffer.pixels[idx + 1] = glowBuffer.pixels[idx + 1] * (1 - blendRatio) + (sumG / count) * blendRatio;
tempBuffer.pixels[idx + 2] = glowBuffer.pixels[idx + 2] * (1 - blendRatio) + (sumB / count) * blendRatio;
tempBuffer.pixels[idx + 3] = centerBright * 0.9 + (sumA / count) * 0.1 * blendRatio;
}
}
}
}
for (var y = 0; y < h; y += pixelStep) {
for (var x = 0; x < w; x += pixelStep) {
var idx = (y * w + x) * 4;
for (var dy = 0; dy < pixelStep && y + dy < h; dy++) {
for (var dx = 0; dx < pixelStep && x + dx < w; dx++) {
var destIdx = ((y + dy) * w + (x + dx)) * 4;
glowBuffer.pixels[destIdx] = tempBuffer.pixels[idx];
glowBuffer.pixels[destIdx + 1] = tempBuffer.pixels[idx + 1];
glowBuffer.pixels[destIdx + 2] = tempBuffer.pixels[idx + 2];
glowBuffer.pixels[destIdx + 3] = tempBuffer.pixels[idx + 3];
}
}
}
}
glowBuffer.updatePixels();
tempBuffer.remove();
}
function compositeLayers() {
p.background(0, 0, 0, 100);
p.blendMode(p.BLEND);
p.image(glowBuffer, 0, 0);
p.blendMode(p.ADD);
p.image(juliaBuffer, 0, 0);
p.blendMode(p.BLEND);
}
function renderOverlayEffects() {
var centerX = p.width / 2;
var centerY = p.height / 2;
var numSpirals = 12;
var spiralPhase = time * 0.5;
for (var s = 0; s < numSpirals; s++) {
var angle = (s / numSpirals) * p.TWO_PI;
var spiralLength = p.width * 0.8;
var points = [];
for (var t = 0; t < spiralLength; t += 5) {
var r = t * 0.002 * zoom;
var theta = angle + t * 0.02 + spiralPhase;
var px = centerX + Math.cos(theta) * r * p.width * 0.4;
var py = centerY + Math.sin(theta) * r * p.height * 0.4;
points.push(p.createVector(px, py));
}
if (points.length > 2) {
p.noFill();
p.stroke(270, 60, 40, 15 + 10 * p.sin(time + s));
p.strokeWeight(0.5);
p.beginShape();
for (var i = 0; i < points.length; i++) {
if (i === 0) {
p.vertex(points[i].x, points[i].y);
} else if (i === 1) {
p.curveVertex(points[i].x, points[i].y);
} else {
p.curveVertex(points[i].x, points[i].y);
if (i < points.length - 1) {
p.curveVertex(points[i].x, points[i].y);
}
}
}
p.endShape();
}
}
var voidCount = 20;
for (var v = 0; v < voidCount; v++) {
var vx = p.noise(v * 0.5, time * 0.3) * p.width;
var vy = p.noise(v * 0.5 + 100, time * 0.3) * p.height;
var vSize = p.noise(v * 0.3) * 100 + 20;
var vAlpha = p.noise(v * 0.7, time * 0.2) * 30 + 5;
p.fill(280, 70, 10, vAlpha);
p.noStroke();
p.beginShape();
for (var a = 0; a < 32; a++) {
var angle = (a / 32) * p.TWO_PI;
var radiusVar = p.noise(angle * 2 + v, time * 0.5) * vSize * 0.5;
var rx = vx + Math.cos(angle) * (vSize * 0.3 + radiusVar);
var ry = vy + Math.sin(angle) * (vSize * 0.3 + radiusVar);
p.vertex(rx, ry);
}
p.endShape(p.CLOSE);
}
if (p.mouseIsPressed) {
p.blendMode(p.ADD);
for (var i = 0; i < 50; i++) {
var angle = p.random(p.TWO_PI);
var dist = p.random(100);
var px = p.mouseX + Math.cos(angle) * dist;
var py = p.mouseY + Math.sin(angle) * dist;
var size = p.random(5, 20) * (1 - dist / 100);
p.noStroke();
p.fill(260, 80, 100, 50 * (1 - dist / 100));
p.ellipse(px, py, size, size);
}
p.blendMode(p.BLEND);
}
}
p.mouseMoved = function() {
};
p.mousePressed = function() {
var angle = p.atan2(p.mouseY - p.height/2, p.mouseX - p.width/2);
var dist = p.dist(p.mouseX, p.mouseY, p.width/2, p.height/2);
targetZoom *= 1.5;
targetPanX += Math.cos(angle) * dist * 0.1 / zoom;
targetPanY += Math.sin(angle) * dist * 0.1 / zoom;
};
p.keyPressed = function() {
if (p.key === 'r' || p.key === 'R') {
resetFractal();
} else if (p.key === 'z' || p.key === 'Z') {
targetZoom = targetZoom > 1 ? 1 : 10;
} else if (p.key === 'm' || p.key === 'M') {
mode = (mode + 1) % 3;
if (mode === 0) { cReal = -0.7; cImag = 0.27015; }
else if (mode === 1) { cReal = -0.8; cImag = 0.156; }
else { cReal = -0.4; cImag = 0.6; }
} else if (p.key === ' ') {
cReal = p.random(-1.5, 1.5);
cImag = p.random(-1.5, 1.5);
}
};
p.windowResized = function() {
var w = container.offsetWidth;
var h = container.offsetHeight;
p.resizeCanvas(w, h);
juliaBuffer.resizeCanvas(w, h);
glowBuffer.resizeCanvas(w, h);
maskBuffer.resizeCanvas(w, h);
};
}; // p5 init stripped
✨ AI 艺术解读
This piece visualizes the dissolution of ego through mathematical recursion — each pixel represents a point in the complex plane where consciousness either escapes to infinity or collapses into infinite depth. The single hue monochrome palette creates a trance-like state while the recursive zoom evokes the sensation of falling through boundaries between existence and void. The ethereal bloom suggests the soft edges of reality, and the spiral overlays hint at sacred geometry underlying all consciousness. Through the mouse-controlled morphing of the fractal, the viewer becomes both observer and participant in their own ego-death ritual.
📝 补充说明
- Pixel step size of 2 balances visual quality with computational efficiency; can be increased to 3-4 for higher frame rates on complex scenes
- Bloom passes accumulate light naturally but each pass increases computation; 2-3 passes optimal for real-time performance
- Julia set parameters can be animated with Perlin noise for continuous morphing effect without user interaction
- Advanced blend modes (ADD, SCREEN) create luminosity impossible with standard alpha blending — essential for psychedelic aesthetic
- The smooth iteration formula (log(log(z))/log(2)) creates anti-aliased fractal boundaries that feel more organic and less computational