この記事は Qiita p5js アドベントカレンダー20日目の記事です。
これはなに
p5.jsが用意している関数について理解を深める記事です。
今回はrandomに似た動きをするnoise()について。
noise()
randomと同様に乱数を生成する関数です。
ただrandomのように値が飛ぶような挙動ではなく、なだらかな値を返してくれます。
リファレンスより
指定された座標におけるパーリンノイズの値を返します。Perlin noise はランダムシーケンスジェネレータで、標準的な random() 関数と比較して、より自然に整列した、調和的な数値の連続を生成します。1980年代にKen Perlinによって発明され、以来、手続き的なテクスチャ、自然な動き、形状、地形などを生成するグラフィックアプリケーションで使用されています。
random()関数との主な違いは、Perlinノイズが無限のn次元空間で定義され、各座標のペアが固定された半ランダム値(プログラムの寿命の間だけ固定されます。計算結果の値は常に0.0から1.0の間になります。ノイズの値は、上の例で示したように、ノイズ空間内を移動してアニメーション化することができます。2次元と3次元は時間として解釈することもできます。(DeepL翻訳)
もっと文章はあるのですが一部抜粋しました。
パーリンノイズとは
ウィキペディア (Wikipedia)- パーリンソンノイズ
パーリンノイズ(英: Perlin noise)とは、コンピュータグラフィックスのリアリティを増すために使われるテクスチャ作成技法。擬似乱数的な見た目であるが、同時に細部のスケール感が一定である。このため制御が容易であり、各種スケールのパーリンノイズを数式に入力することで多彩なテクスチャを表現できる。パーリンノイズによるテクスチャは、CGIで自然な外観を物に与えるためによく使われる。
ケン・パーリンが Mathematical Applications Group, Inc. で勤務しているときに開発した。彼はこの業績により、1997年、映画芸術科学アカデミーからアカデミー科学技術賞(Technical Achivement)を受賞した。
ケン・パーリンさんという方が開発した手法で、処理が軽いにもかかわらず自然の質感を簡単に出せるとのこと。
例えば炎の表現、波のうねりなど時間軸が関わる表現もこのパーリンノイズが使われているそうです。
そしてこのパーリンノイズの処理を行ってくれるのがnoise関数。
なんだかありがたい感じがします。
Type
noise(x: number, y?: number, z?: number): number;
引数
- x 横軸の値
- y 縦軸の値
- z Z軸の値
引数の値から乱数を生成して返します。
この返り値がrandom()と違い、自然な(流れるような)数値になります。
試してみる
p5.jsの関数まとめ part.14 bezierVertex()を書いたときに学んだベジェ曲線を利用します。
function setup() {
createCanvas(600, 600);
}
let _x = 0
let _y = 0
function draw() {
background(0);
fill('white')
// 制御点のX座標
_x = _x + 0.01
x = noise(_x)*width
// 制御点のY座標
_y = _y + 0.01
y = noise(_y)*height
// Vertex
beginShape();
vertex(0, 300);
bezierVertex(x, y, x, y, 600, 300);
endShape();
// 制御点の座標をpoint()で描画
push()
stroke('red')
strokeWeight(10)
point(x, y)
pop()
// 制御点の座標を文字で出力
textSize(20)
text(`X: ${x}`, 20, 20)
text(`Y: ${y}`, 20, 50)
}
おおすごい!ぬるぬる動いています!
変数_x
に+0.01をしています。
これはnoiseの変化量を調節するためです。
これを+1にするとrandom()
のようにすごいスピードで動きました。
_x = _x + 0.01
そして面白いのは出力している数値です。よく見たらxとyの数値が一緒・・。
noise()に渡す引数やその変化量が同じだと計算して返す値が同じであることに気づきました。
こちらの記事を読んでみると
noise()に渡る引数はシード値なんだそうです。
確かに両方のnoiseに渡している引数は同じ値なので、xとyが同じ数値になるのも納得です。
ではxのnoise()に第二引数を渡してみます。
x = noise(_x, _y)*width
今度はxとyでnoiseの返り値が変わりました!
引数yを渡した場合はそれを加味した乱数が返ることが分かります。
思い切りバラバラな乱数が欲しいときはrandom()
を、
ある程度自然でその速度(時間の流れ)にコントロールを持たせたい場合にはnoise
を使用するとよさそうです。
参考になる記事
使い勝手がいい分本当に深い関数だと思いました。
今回調べている中でこれまで紹介したものの他にも非常に参考になる記事がありましたので、ここで紹介させていただきます。
p5.jsで「パーリンノイズ」のスゴさを思い知る
変化量の比較など、細かい部分の検証を行っている記事です。
とても面白い・・・
Processing/p5.js の noise() で遊ぼう! 前編
noise関数ってなに?というところから詳しく学べる記事だと思います。
こちらもかなり詳しく説明してくださっています。
p5.js reference | noise()
最後にリファレンスもここに置いておきます。