P 5による流れ場と雑音アルゴリズムjs


ノイズアルゴリズム


以前に、私はノイズアルゴリズムが異なる手続き内容生成技術でどのように使われるかについてわかりました.これは私がこれらのテクニックを使用することができたいくつかのリソースに私をリードP5.js . ノイズアルゴリズムは、手続き内容の生成のすべての場所で使用されますが、それらはまた、n次元上のpsuedoランダム値の分布から選択するときに必要となる任意の種類の補間に便利です.

流れ場



View Code
上記の例では、所望の流れのような効果を得るために様々な特徴のために3次元Perlinノイズを使用する可視化を作成しました.これには:
  • 赤、青、緑の3 Dノイズカラーフィールド
  • 各グリッドセルの角度ベクトル
  • 各角度ベクトルの大きさベクトル
  • 新しい連続粒子導入のための雑音
  • 古い粒子を除去するための雑音
  • 各粒子は、速度、加速度、位置、最大速度を持つポイントのシミュレーション以上のものであり、力ベクトルとして位置インデックスで各ベクトルを適用することによって方向に従うようにフローベクトルフィールドを使用します.グリッド内の各ベクトルを示すことによってどのように流れのフィールドを変更する方向を見ることができます.

    View Code
    負と正の等級ベクトルのA組み合わせを使用している方法に注意してください.大きさは、−5と5の間の値にマップされた3次元ノイズ値によって計算される.あなたは、正の値だけまたは負の値と流れはほとんど一方向に移動しますこれに変更することができます.
    処理ループは、行と列(グリッドセルサイズに沿って計算)を介して移動し、各次元で異なるオフセットを使用することに興味を持っていた各機能のノイズ値を生成することによって動作します.各ノイズ特徴は0と1の間の値を生成します(少なくともp 5では、他のライブラリではこの値は通常- 1と1の間になります).指定した機能のスケールで値を乗算します.2つの値を2つの角で倍加する角度については、色の値を255に換算します.機能のほとんどは、単により多くのグローバルZオフセット時間の要因として使用されるXとYグリッドに沿って繰り返して3 Dノイズマップの特定のオフセットを使用します.XおよびYオフセットは、ノイズ関数に沿って移動するステップサイズでインクリメントされ、Zは、時間に応じて描画ループが呼び出されるたびにインクリメントされます.私は、同じZオフセットに必ずしも縛られない別々の増分項の大きさオフセットを増やしています、しかし、それは異なるステップサイズと同様に時間に従って機能します.
    var stepSizes = {
        x: 0.1,
        y: 0.1
        z: 0.005,
        m: 0.0005
    };
    var incStart = 0.005;
    var cellSize = 10;
    var zoff = 0;
    var magOff = 0;
    var rows, cols;
    var features = {
        r: { scale: 255 },
        g: { scale: 255, offset: 100 },
        b: { scale: 255, offset: 200 },
        angle: { scale: TWO_PI },
        m: { scale: 1 }
    };
    
    var numParticles = 1000;
    var particles = [];
    var flowfield, flowcolorfield;
    
    function setup() {
        createCanvas(800, 350);
        pixelDensity(1);
    
        cols = floor(width / cellSize);
        rows = floow(height / cellSize);
        flowfield = new Array(rows * cols);
        flowcolorfield = new Array(rows * cols);
        particles = new Array(numParticles);
        for (let i = 0; i < particles.length; i++) {
            particles[i] = new Particle();
        }
    
        background(0);
    }
    
    function calcNoise(k, xoff, yoff, zoff) {
        let f = features[k];
        f.offset = f.offset || 0;
        let n = noise(xoff + f.offset, yoff + f.offset, zoff);
        let amplitude = f.scale || f.amplitude || 1;
        return n * amplitude;
    }
    
    function draw() {
        // layering to gradually fade out
        background(color(0, 0, 0, 5));
    
        // loop over grid to calculate noise
        let yoff = 0;
        for (let y = 0; y < rows; y++) {
            let xoff = 0;
            for (let x = 0; x < cols; x++) {
                let r = calcNoise('r', xoff, yoff, zoff);
                let g = calcNoise('g', xoff, yoff, zoff);
                let b = calcNoise('b', xoff, yoff, zoff);
                let angle = calcNoise('angle', xoff, yoff, zoff);
                let v = p5.Vector.fromAngle(angle);
                let m = map(calcNoise('m', xoff, yoff, magOff), 0, 1, -5, 5);
                v.setMag(m);
    
                xoff += stepSizes.x;
    
                let index = x + y * cols;
                flowfield[index] = v;
                flowcolorfield[index] = [r,g,b];
            }
            yoff += stepSizes.y;
        }
        magOff += stepSizes.m;
        zoff += stepSizes.z;
    
        for (let i = 0; i < particles.length; i++) {
            particles[i].follow(flowfield, flowcolorfield);
            particles[i].update();
            particles[i].edges();
            particles[i].show();
        }
    }
    
    この特定のインプリメンテーションは、各々のノイズ機能が事項ノイズループの範囲内でセットアップであるようにリファクタリングされることができた.ノイズループは特に興味深いですあなたが同じ値を生成するためにノイズ関数の同じオフセットで起動する限り、あなたは完璧なループを作成することができます.

    ノイズループ



    View Code
    上記の例では、ノイズループの概念を使用している.実際、私は徐々に同じ値に戻る限り、任意の値を選ぶことができました.円は、単にこの簡単に実装することができます.すべての機能は、ノイズループに変えることができる、それは私がポジション、色、サイジングとアルファに行ったことはかなりです.
    function noiseLoop(diameter, min, max, rnd) {
      let cx = random(rnd || 1000);
      let cy = random(rnd || 1000);
      return function (angle) {
        let xoff = map(cos(angle), -1, 1, cx, cx + diameter);
        let yoff = map(sin(angle), -1, 1, cy, cy + diameter);
        let zoff = sin(angle) * 0.001;
        let r = noise(xoff, yoff, zoff);
        return map(r, 0, 1, min, max);
      };
    }
    
    function Particle() {
      this.xn = noiseLoop(0.05, -width, width * 2);
      this.yn = noiseLoop(0.05, -height, height * 2);
      this.rn = noiseLoop(0.5, 0, 255);
      this.gn = noiseLoop(0.5, 0, 255);
      this.bn = noiseLoop(0.5, 0, 255);
      this.dn = noiseLoop(0.5, 1, 10);
      this.an = noiseLoop(1, 5, 200);
    
      this.render = function (a) {
        noStroke();
        fill(this.rn(a), this.gn(a), this.bn(a), this.an(a));
        circle(this.xn(a), this.yn(a), this.dn(a));
      };
    }
    
    var particles = new Array(200);
    var totalFrames = 240;
    var counter = 0;
    
    function setup() {
      createCanvas(800, 350);
      for (let i = 0; i < particles.length; i++) {
        particles[i] = new Particle();
      }
    }
    
    function draw() {
      background(0);
      percent = (counter % totalFrames) / totalFrames;
      let a = percent * TWO_PI;
      for (let i = 0; i < particles.length; i++) {
        particles[i].render(a);
      }
      counter++;
    }
    

    地形発生


    ノイズ関数のための時間の三次元を使用した2次元可視化とともに、3次元ノイズは地形生成アルゴリズムで広範囲に使用されます.これは、実際のシミュレーションを生成することなく、少し有機的な何かを必要とする基礎的な概念になります.下記の例では、私はZオフセットを時間の要因として調整しています(前の例でしたように)、そして、突然、地形は水のためのアニメーションとしてまともに働きます.

    シンプレックスノイズ


    フォローアップとして、私は、処理におけるPerlinノイズの実装を発見したP5.js ケンペリンによって発明された元の1983年版と同じアルゴリズムを使用します.このインプリメンテーションは、Perlin雑音アルゴリズムへの改善によって2001年に後で解決された顕著な方向性アーチファクトを持ちます.ケンペリン自身もまた、物事を大幅にスムーズかつ迅速にするシンプレックスと呼ばれる別のアルゴリズムを作成しました.残念ながら、彼もそのアルゴリズムを特許しました.我々にとって幸運なことに、特許の規則の下にある特定の変種を取り出すアルゴリズムの一部を増やすオープンソース実装があります.シンプレックスは以下の利点を有するWiki )
  • より低い計算量,少ない乗算器
  • O(n * 2 ^ n)の代りに計算量の少ないo(n*n)を持つ高次元へのスケール
  • 目立つ方向性アーチファクト
  • 安く計算されることができるどこでも、よく定義されて連続的な勾配
  • ハードウェアで実装しやすい
  • オープンシンプレックス(異なる言語、プラットフォームなど)で見つけた実装の数が多い.私はJavaScriptでシンプレックスバージョンを使用して私は古典的なPerlinノイズとシンプレックスから下記の私の波デモで見ていたものの違いを実証する.

    View Code
    シンプレックスのバージョンはかなりスムーズであり、以前の例では古典的なPerlinノイズで取得する方向性のアーティファクトと同じようなものではありません.もちろん、これらのデモの両方は、ハードウェア加速の下でよりよく働きます.

    結論


    アルゴリズムの実際の根底にある実装は、この記事がレイアウトされているよりも少し深くなっているのに対して、私はこのスペースをより詳細に探求して、少なくとも興味深いとユニークなアートワークを生成するためのテクニックに自分自身を公開することができてうれしいです.抽象化のユーティリティを認識したら、抽象化はいくつかの抽象化、基本的な実装の詳細を理解するのは難しいが、抽象化は様々な方法で適用できる便利なツールです.あなたが補間、スムージング、グラデーションのような基本的な概念を理解し、別の幾何学で動作するように学ぶ限り、それは数学的な式のnitty gritty詳細を知るために不可欠ではない.私は他のタイプのノイズ機能を探ることを望んでいますcellular noise 私は手続きのコンテンツの生成に深く飛び込むように.

    参考文献

  • ブックオブシャドウhttps://thebookofshaders.com/11/
  • パーリンノイズhttps://en.wikipedia.org/wiki/Perlin_noise
  • シンプレックスノイズhttps://en.wikipedia.org/wiki/Simplex_noise
  • シンプレックスhttp://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
  • ベクトル場https://en.wikipedia.org/wiki/Vector_field
  • 列車の流れ場のコーディング
  • あなたがこの記事が好きならば、私にフォローなどを与えてください.また、同様のコンテンツの私のチェックアウト!
    歓声🍻