特性
Processing, openFrameworksには標準でノイズ関数が用意されています。
下記はそれぞれのリファレンスへのリンクになります。
Processing noise関数
openFrameworks ofNoise関数
どちらの関数も指定した引数に基づき、0.0から1.0までの間で連続的に変化する値を返す関数です。言葉だけでは良く分からないと思いますので、引数を0から0.05づつ増加させたnoise関数の返り値を羅列したものを見てみましょう。
雰囲気を掴んで貰えるよう100行用意しましたので、値の変化に注目しながらスクロールを進めて下さい。また、末尾に出力した際に使用したProcessingのソースコードもありますので、興味のある方は自身の環境で実行してみてください。
関数名(引数) : 返り値
noise(0.00) : 0.11172
noise(0.05) : 0.11978
noise(0.10) : 0.13734
noise(0.15) : 0.15224
noise(0.20) : 0.15946
noise(0.25) : 0.16817
noise(0.30) : 0.18849
noise(0.35) : 0.21029
noise(0.40) : 0.21221
noise(0.45) : 0.19755
noise(0.50) : 0.19243
noise(0.55) : 0.20360
noise(0.60) : 0.22071
noise(0.65) : 0.24283
noise(0.70) : 0.27743
noise(0.75) : 0.29258
noise(0.80) : 0.28837
noise(0.85) : 0.27902
noise(0.90) : 0.25409
noise(0.95) : 0.21525
noise(1.00) : 0.19511
noise(1.05) : 0.18889
noise(1.10) : 0.18133
noise(1.15) : 0.18880
noise(1.20) : 0.20647
noise(1.25) : 0.22240
noise(1.30) : 0.24995
noise(1.35) : 0.29253
noise(1.40) : 0.32501
noise(1.45) : 0.35294
noise(1.50) : 0.35901
noise(1.55) : 0.33509
noise(1.60) : 0.30289
noise(1.65) : 0.29044
noise(1.70) : 0.28264
noise(1.75) : 0.26519
noise(1.80) : 0.22681
noise(1.85) : 0.17644
noise(1.90) : 0.13467
noise(1.95) : 0.10305
noise(2.00) : 0.09137
noise(2.05) : 0.09223
noise(2.10) : 0.09121
noise(2.15) : 0.08441
noise(2.20) : 0.08133
noise(2.25) : 0.08813
noise(2.30) : 0.09703
noise(2.35) : 0.10910
noise(2.40) : 0.13564
noise(2.45) : 0.18318
noise(2.50) : 0.21886
noise(2.55) : 0.24520
noise(2.60) : 0.28917
noise(2.65) : 0.34038
noise(2.70) : 0.39194
noise(2.75) : 0.43608
noise(2.80) : 0.47592
noise(2.85) : 0.51949
noise(2.90) : 0.55355
noise(2.95) : 0.56971
noise(3.00) : 0.57340
noise(3.05) : 0.56168
noise(3.10) : 0.53427
noise(3.15) : 0.50925
noise(3.20) : 0.49376
noise(3.25) : 0.48834
noise(3.30) : 0.49272
noise(3.35) : 0.50014
noise(3.40) : 0.50059
noise(3.45) : 0.48841
noise(3.50) : 0.46992
noise(3.55) : 0.44139
noise(3.60) : 0.39598
noise(3.65) : 0.34947
noise(3.70) : 0.29876
noise(3.75) : 0.25462
noise(3.80) : 0.23433
noise(3.85) : 0.22501
noise(3.90) : 0.20244
noise(3.95) : 0.17800
noise(4.00) : 0.16732
noise(4.05) : 0.17382
noise(4.10) : 0.18365
noise(4.15) : 0.18027
noise(4.20) : 0.16291
noise(4.25) : 0.14408
noise(4.30) : 0.13240
noise(4.35) : 0.12442
noise(4.40) : 0.11274
noise(4.45) : 0.10151
noise(4.50) : 0.09623
noise(4.55) : 0.10106
noise(4.60) : 0.10735
noise(4.65) : 0.10076
noise(4.70) : 0.08598
noise(4.75) : 0.08197
noise(4.80) : 0.09368
noise(4.85) : 0.11549
noise(4.90) : 0.14569
noise(4.95) : 0.16817
お疲れ様でした。
それでは、列挙された値から読み取れるポイントを説明します。
ポイント1 : 0.0 – 1.0
ご覧の通り返り値は0.0から1.0までの間の数字です。この範囲以外の数字が表れる事はありません。ノイズ関数は0.0から1.0までの数字を取得するための関数なのです。ProcessingやopenFrameworksでは、この0.0から1.0までの数字を、動きや色などの表現・見せ方に利用していきます。
ポイント2 : 連続的な変化
各行の前後行で返り値を見比べて見て下さい。列挙されたケースでは、その差は大きくても0.03程に収まっています。これは引数を0.05増やす(又は減らす)事によって、現在の引数の返り値との差が、大きくても0.03程度の値を取得出来る事を表しています。
ポイント3 : スケール
更に、引数を4.9から0.01づつ4.95まで増加させた場合の返り値を用意しました。
noise(4.90) : 0.14569
noise(4.91) : 0.15098
noise(4.92) : 0.15586
noise(4.93) : 0.16059
noise(4.94) : 0.16450
noise(4.95) : 0.16817
noise(4.90) : 0.14569 と noise(4.95) : 0.16817 の値に注目して見てください。先ほどの100行にも同じ引数、返り値を持つ値を見つける事が出来ます。このことから、引数に与える数字の増減の値を小さくすれば、より変化の小さい返り値を、引数の増減を大きくすれば、変化の大きな返り値を取得する事が出来るという事です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// // ダンププログラム // void setup() { float noiseArg; for(int i = 0; i < 100; i++) { noiseArg = i * 0.05; println(String.format("noise(%.2f) : %.5f", noiseArg, noise(noiseArg))); } println(); for(int i = 0; i < 6; i++) { noiseArg = 4.9 + i * 0.01; println(String.format("noise(%.2f) : %.5f", noiseArg, noise(noiseArg))); } } |
今回、列挙した値を出力したProcessingのソースコードです。コンソールの部分に値が表示されます。なお、実行するたびに返り値の値は変わります。
値の利用
ここからはノイズ関数から得られる値をどうやって表現へ変換するかの例をいくつか挙げていきます。Processingでのソースコードも併せて記載しておりますので、ご自身の環境でも動かしながらご確認下さい。
サンプル1 : ノイズ値 to サイズ
次のサンプルはノイズ値を円の半径に利用しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// // ノイズ値 to サイズ // float noiseArg; void setup() { size(400, 300); noiseArg = 0; } void draw() { background(39); float noiseValue = noise(noiseArg); float radius = noiseValue * 300; ellipse(width / 2, height / 2, radius, radius); noiseArg += 0.05; } |
中心座標にある円の半径が大きくなったり小さくなったり変化をしています。この動きはノイズ関数から得られた値を元に半径を変化させる事で実現しています。
1 |
float noiseValue = noise(noiseArg); |
このコードでノイズ関数から取得した値を変数noiseValueへ書き込んでいます。
1 2 |
float radius = noiseValue * 300; ellipse(width / 2, height / 2, radius, radius); |
更に変数noiseValueへ300をかけた値を変数radiusへ書き込みます。ノイズ関数の返り値は、ポイント1で示したように0.0 ~ 1.0までの間を取りますので、radiusは0.0 ~ 300.0までのいづれかの値となることになります。
1 |
noiseArg += 0.05; |
また、フレーム毎に半径が変化するのは、変数noiseArgをdraw関数内で0.05づつ増加させ、ノイズ関数からの返り値を変化させているからです。この増加量を変化させると変化の仕方が変わります。
ポイント3で説明したスケールを見た目として実感できると思うので、色々な値に変えて試してみて下さい。(例) 0.01, 0.0, 1.5 etc..
サンプル2 : ノイズ値 to カラー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// // ノイズ値 to カラー // float noiseArgR, noiseArgG, noiseArgB; void setup() { size(400, 300); noiseArgR = random(100); noiseArgG = random(100); noiseArgB = random(100); } void draw() { background(239); float r = noise(noiseArgR) * 255; float g = noise(noiseArgG) * 255; float b = noise(noiseArgB) * 255; fill(r, g, b); ellipse(width / 2, height / 2, 250, 250); noiseArgR += 0.05; noiseArgG += 0.05; noiseArgB += 0.05; } |
こちらのサンプルではノイズ関数を使って円の色を変化させています。
1 2 3 4 5 6 |
float r = noise(noiseArgR) * 255; float g = noise(noiseArgG) * 255; float b = noise(noiseArgB) * 255; fill(r, g, b); ellipse(width / 2, height / 2, 250, 250); |
色を指定する為に、RGBの値をそれぞれノイズ関数で0.0 ~ 255.0のいづれかの値へ変化させています。サンプル1との違いは変化させる対象の値が3つ(R, G, B)存在するという事です。
1 2 3 |
noiseArgR = random(100); noiseArgG = random(100); noiseArgB = random(100); |
その為、引数用の変数の初期化に0ではなく、random関数の返り値を指定しています。これは全て同じ初期値を指定するとR, G, Bの値がすべて同じになってしまうため、色の変化が白と黒になってしまうためです。
このように複数の値を別々に変化させたい場合は、randomを使って初期化する方法があります。
サンプル3 : ノイズ値 to 位置
次のサンプルは位置情報(x, y)にノイズ値を利用しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/// /// ノイズ値 to 位置 /// float noiseArgX, noiseArgY; void setup() { size(400, 300); noiseArgX = random(100); noiseArgY = random(100); } void draw() { background(239); float x = noise(noiseArgX) * width; float y = noise(noiseArgY) * height; ellipse(x, y, 30, 30); noiseArgX += 0.01; noiseArgY += 0.01; } |
XとYという二つの値を操作するという点は先ほどのサンプルと似ていますが、絵としての見え方はだいぶ変わります。
サンプル4 : ノイズ値 to 文字
0.0から1.0までの数字を取る値が我々の身近にあります。それは百分率です。例えば、”0.1″という少数は”10%”を表しまし、”0.39″は39%を表します。
その特性を使って、百分率を文字として出力するサンプルです。文字として変化を眺めると、絵で見るのとは違う見え方もあるかと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/// /// ノイズ値 to 文字 /// float noiseArg; void setup() { size(400, 300); textSize(100); textAlign(RIGHT); noiseArg = random(100): } void draw() { background(39); float percent = noise(noiseArg) * 100; text(String.format("%.1f %%",percent), width, height / 2 + 25); noiseArg += 0.01; } |
多次元
ここまでの説明は、全て引数が一つのノイズ関数のみを使ってきました。しかし、最初に挙げたリファレンス先にある通り、Processingでは3つまで、openFrameworksでは4つまで指定する事が出来ます。
思ったよりボリュームが増えてしまったため、それらについてはココで説明はしませんが、1つの引数のノイズ関数に慣れてきたら、2つ、3つのパターンも触って行きましょう。引数が増えても0.0 – 1.0までの返り値を返すという動きに変化はありません。
以下に一例として、3つの引数を使ったノイズ関数を使ったサンプルを置いておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
/// /// 3次元のノイズ関数 /// float noiseArg; void setup() { size(400, 300); noiseArg = random(100); } void draw() { background(239); int radius = 200; beginShape(); for(int deg = 0; deg < 360; deg += 1) { float x = radius * cos(radians(deg)) + width / 2; float y = radius * sin(radians(deg)) + height / 2; float noiseRadius = noise(x * 0.005, y * 0.005, noiseArg) * radius; x = noiseRadius * cos(radians(deg)) + width / 2; y = noiseRadius * sin(radians(deg)) + height / 2; vertex(x, y); } endShape(CLOSE); noiseArg += 0.005; } |
以上です。
ご意見や疑問ながどありましたら、自己紹介にあります各種連絡先に下さい。
また、普段の投稿でもノイズ関数は使っておりますので、Noiseのタグで使用例なども結構な数があると思います。(openFrmeworksが多いです)
最後まで読んで頂き、ありがとうございました。