Multidimensional Simplex Noise Topography

📅 April 23, 2026 🏷️ art
worth-a-look simplex-noise topography flow-field particle-dynamics emergence high-dimensional-noise generative-art
Generated by GridFlow AI | Tags: simplex-noise, topography, flow-field, particle-dynamics, emergence, high-dimensional-noise, generative-art

💡 AI 提示词

Create a multidimensional simplex noise topography visualization where particles flow through 4D noise-driven vector fields, creating emergent landscape-like patterns with color gradients from the noise dimensions

🔧 核心算法要点

  1. Sample 3D simplex noise for base angle computation across a grid aligned to canvas dimensions
  2. Overlay 4D simplex noise for additional angular complexity creating multidimensional flow paths
  3. Apply a third high-dimensional noise layer to modulate flow field strength dynamically
  4. Initialize particle system with density proportional to canvas resolution for consistent detail
  5. Each particle reads flow vector from grid cell and updates position creating topographic trace patterns
  6. Color each particle using separate noise samples mapped to HSB color space for dimensional variety

🎨 原始代码

var sketch = function(p) {
  var particles = [];
  var cols, rows;
  var scl = 8;
  var flowField = [];
  var timeOffset = 0;
  var noiseScale = 0.003;
  var dim4Scale = 0.002;
  var container;

  p.setup = function() {
    container = document.getElementById('p5-wrapper');
    p.createCanvas(container.offsetWidth, container.offsetHeight).parent(container);
    p.colorMode(p.HSB, 360, 100, 100, 100);
    p.background(20, 30, 8);
    cols = p.floor(p.width / scl);
    rows = p.floor(p.height / scl);
    p.initParticles();
    p.noStroke();
  };

  p.initParticles = function() {
    particles = [];
    var count = p.map(p.width * p.height, 0, 1920 * 1080, 800, 3200);
    for (var i = 0; i < count; i++) {
      particles.push(p.createVector(p.random(p.width), p.random(p.height)));
    }
  };

  p.draw = function() {
    p.background(20, 30, 8, 18);
    p.updateFlowField();
    p.moveParticles();
    p.drawTopography();
    timeOffset += 0.004;
  };

  p.updateFlowField = function() {
    for (var y = 0; y < rows; y++) {
      for (var x = 0; x < cols; x++) {
        var index = x + y * cols;
        var n3d = p.noise(x * noiseScale, y * noiseScale, timeOffset);
        var n4d = p.noise(x * noiseScale + 1000, y * noiseScale + 1000, timeOffset * 0.7, timeOffset * 1.3);
        var nHigh = p.noise(x * dim4Scale + 2000, y * dim4Scale + 2000, timeOffset * 2.0, timeOffset * 0.5);
        var angle = n3d * p.TWO_PI * 4 + n4d * p.TWO_PI * 2 + nHigh * p.TWO_PI;
        var strength = p.map(nHigh, 0, 1, 0.8, 3.5);
        var v = p5.Vector.fromAngle(angle);
        v.mult(strength);
        flowField[index] = v;
      }
    }
  };

  p.moveParticles = function() {
    for (var i = 0; i < particles.length; i++) {
      var pt = particles[i];
      var col = p.floor(pt.x / scl);
      var row = p.floor(pt.y / scl);
      var index = col + row * cols;
      if (flowField[index]) {
        pt.add(flowField[index]);
      }
      var bounce = 0.5;
      if (pt.x < 0) { pt.x = 0; }
      if (pt.x > p.width) { pt.x = p.width; }
      if (pt.y < 0) { pt.y = 0; }
      if (pt.y > p.height) { pt.y = p.height; }
      if (col >= 0 && col < cols && row >= 0 && row < rows) {
        var nColor = p.noise(col * noiseScale + 3000, row * noiseScale + 3000, timeOffset * 1.5);
        var hue = p.map(nColor, 0, 1, 180, 320);
        var sat = p.map(p.dist(pt.x, pt.y, p.width * 0.5, p.height * 0.5), 0, p.width * 0.7, 100, 40);
        var bri = p.map(p.noise(pt.x * 0.01, pt.y * 0.01, timeOffset), 0, 1, 60, 95);
        p.fill(hue, sat, bri, 55);
        p.ellipse(pt.x, pt.y, p.random(1.5, 4.5), p.random(1.5, 4.5));
      }
      if (p.random() < 0.003) {
        pt.x = p.random(p.width);
        pt.y = p.random(p.height);
      }
    }
  };

  p.drawTopography = function() {
    for (var y = 0; y < rows; y++) {
      for (var x = 0; x < cols; x++) {
        var index = x + y * cols;
        var n3d = p.noise(x * noiseScale, y * noiseScale, timeOffset);
        var n4d = p.noise(x * noiseScale + 1000, y * noiseScale + 1000, timeOffset * 0.7, timeOffset * 1.3);
        var combined = (n3d + n4d) * 0.5;
        var hue = p.map(combined, 0, 1, 200, 280);
        var bri = p.map(combined, 0, 1, 5, 25);
        var alpha = p.map(combined, 0, 1, 8, 30);
        p.fill(hue, 60, bri, alpha);
        p.rect(x * scl, y * scl, scl, scl);
      }
    }
  };

  p.windowResized = function() {
    p.resizeCanvas(container.offsetWidth, container.offsetHeight);
    cols = p.floor(p.width / scl);
    rows = p.floor(p.height / scl);
    flowField = [];
    p.initParticles();
  };
}; // p5 init stripped

✨ AI 艺术解读

This piece visualizes the invisible topography of higher-dimensional noise fields by allowing thousands of particles to surf through mathematically derived force landscapes. The emergent ridges and valleys form organic terrain-like structures that breathe and shift as time advances through the fourth dimension. By mapping multiple noise coordinates to hue, saturation, and brightness, each particle becomes a living point sampling the structure of abstract mathematical space, making the imperceptible dimensions tangible through visual emergence.

📝 补充说明

  • Using p.noise() with 4+ arguments activates p5.js built-in simplex noise in higher dimensions for richer field data
  • Particle count scales with canvas area to maintain visual density across different viewport sizes
  • Background with alpha 18 creates natural motion trails without explicit trail storage arrays
  • The flow field grid uses scl (scale) factor to balance performance against visual smoothness
  • Resetting particles at random intervals (0.3% per frame) prevents stagnation and maintains fresh topographic exploration