Fractal Aurora Ice Formation

📅 April 23, 2026 🏷️ art
worth-a-look ice perlin noise generative recursive blue cyan winter cold
Generated by GridFlow AI | Tags: ice, perlin noise, generative, recursive, blue, cyan, winter, cold

💡 AI 提示词

Perlin noise driven ice crystal formation with recursive branching, ethereal translucent rendering, deep blue and cyan color palette, emergence through simple growth rules, organic fractal patterns

🔧 核心算法要点

  1. Use Perlin noise field to perturb crystal growth direction at each step
  2. Implement recursive branching where each crystal can spawn 2 sub-branches
  3. Accumulate drawn segments over time for persistent crystal structure
  4. Vary branch properties (length, thickness, hue) based on recursion depth
  5. Apply translucent rendering with low alpha for ethereal ice effect
  6. Trigger regeneration after crystals fill canvas or periodically
  7. Normalize noise coordinates to prevent extreme directional jumps

🎨 原始代码

var sketch = function(p) {
    var branches = [];
    var maxDepth = 7;
    var seed;
    var noiseScale = 0.008;
    
    p.setup = function() {
        var container = document.getElementById('p5-wrapper');
        p.createCanvas(container.offsetWidth, container.offsetHeight).parent(container);
        p.colorMode(p.HSB, 360, 100, 100, 1);
        p.strokeCap(p.ROUND);
        p.frameRate(30);
        seed = p.random(10000);
        initCrystals();
    };
    
    function initCrystals() {
        branches = [];
        var cx = p.width / 2;
        var cy = p.height / 2;
        var numStarts = Math.floor(p.random(4, 8));
        
        for (var i = 0; i < numStarts; i++) {
            var baseAngle = (p.TWO_PI / numStarts) * i + p.random(-0.3, 0.3);
            branches.push({
                x: cx,
                y: cy,
                angle: baseAngle,
                length: 0,
                maxLength: p.random(120, 200),
                speed: p.random(0.6, 1.2),
                thickness: p.random(2.5, 4),
                depth: 0,
                hue: 210 + p.random(-20, 20),
                noiseOffset: p.random(1000),
                branchesSpawned: 0
            });
        }
    }
    
    p.draw = function() {
        p.background(220, 40, 6);
        
        for (var i = branches.length - 1; i >= 0; i--) {
            var b = branches[i];
            
            // Get Perlin noise for direction perturbation
            var noiseVal = p.noise(b.x * noiseScale, b.y * noiseScale, b.noiseOffset);
            var angleOffset = (noiseVal - 0.5) * 0.4;
            
            // Calculate growth rate with easing
            var remainingRatio = 1 - b.length / b.maxLength;
            var growthRate = b.speed * remainingRatio * remainingRatio;
            
            // Store previous position
            var prevX = b.x;
            var prevY = b.y;
            
            // Update position
            b.x += p.cos(b.angle) * growthRate;
            b.y += p.sin(b.angle) * growthRate;
            b.length += growthRate;
            
            // Perturb angle with noise
            b.angle += angleOffset * remainingRatio;
            
            // Calculate thickness based on depth
            var thicknessFactor = p.map(b.depth, 0, maxDepth, 1.0, 0.35);
            var currentThickness = b.thickness * thicknessFactor;
            
            // Calculate color based on depth
            var currentHue = (b.hue + p.map(b.depth, 0, maxDepth, 0, 25)) % 360;
            var alpha = p.map(b.depth, 0, maxDepth, 0.55, 0.2);
            
            // Draw crystal segment
            p.stroke(currentHue, 55, 100, alpha);
            p.strokeWeight(currentThickness);
            p.line(prevX, prevY, b.x, b.y);
            
            // Spawn new branches at intervals
            if (p.frameCount % 20 === 0 && b.depth < maxDepth && branches.length < 600) {
                var branchNoise = p.noise(b.x * 0.006, b.y * 0.006, b.noiseOffset + 50);
                var branchChance = p.map(branchNoise, 0, 1, 0.15, 0.35);
                
                if (p.random() < branchChance && b.length > 25) {
                    for (var j = 0; j < 2; j++) {
                        var angleOffset = (j === 0 ? -1 : 1) * (p.PI / 5 + p.noise(b.noiseOffset + j * 7) * p.PI / 3);
                        branches.push({
                            x: b.x,
                            y: b.y,
                            angle: b.angle + angleOffset,
                            length: 0,
                            maxLength: b.maxLength * p.random(0.55, 0.75),
                            speed: b.speed * p.random(0.7, 0.9),
                            thickness: b.thickness * p.random(0.65, 0.8),
                            depth: b.depth + 1,
                            hue: b.hue + p.random(-10, 10),
                            noiseOffset: b.noiseOffset + p.random(50, 100),
                            branchesSpawned: 0
                        });
                    }
                    b.branchesSpawned++;
                }
            }
        }
        
        // Reset when crystals finish growing
        if (branches.length === 0) {
            p.noLoop();
            setTimeout(function() {
                initCrystals();
                p.loop();
            }, 1500);
        }
    };
    
    p.windowResized = function() {
        var container = document.getElementById('p5-wrapper');
        p.createCanvas(container.offsetWidth, container.offsetHeight).parent(container);
        initCrystals();
    };
};
// p5 init stripped

✨ AI 艺术解读

This piece explores the delicate beauty of ice crystal formation through the lens of procedural generation. The crystals grow from central points, their paths guided by Perlin noise, creating organic branching structures that evoke the natural hexagonal symmetry of real ice while maintaining a dreamlike quality. The gradual accumulation and translucent rendering suggest the slow, patient formation of frost on a winter window, where each branch carries the memory of its growth. The deep blue-to-cyan palette transitions reflect both the depth of the crystal structure and the subtle variations in how light passes through ice of different thicknesses.

📝 补充说明

  • Perlin noise coordinates should be scaled appropriately to prevent erratic directional changes
  • Using squared remainingRatio for growth rate creates natural deceleration as branches reach max length
  • Branch spawning probability controlled by secondary noise layer adds organic unpredictability
  • HSB color mode with varying alpha creates authentic ice-like translucency
  • Recursive depth affects both thickness and hue for visual hierarchy and depth perception