※現在、ブログ記事を移行中のため一部表示が崩れる場合がございます。
順次修正対応にあたっておりますので何卒ご了承いただけますよう、お願い致します。

Processingのnoise関数を使うと興味深い模様が簡単にできる


2019年 08月 27日

次のような模様を見たことが無いだろうか?

これは、Processingに用意されているnoize関数を用いることで、簡単に作ることができる。

パーリンノイズ(Perlin noise) と呼ばれるこの関数は、自然なテクスチャを表現するために用意されたもので、雲を表現するためなどに使われる。

PerlinNoise1.png

この画像は、以下のプログラムを実行すると、静止画として表示されたものである。

void setup() {
background(255);
colorMode(HSB, 100);
size(500, 500);
strokeWeight(1);
}

void draw() {
for ( int x=0; x<width; ++x ) {
for ( int y=0; y<height; ++y ) {
float co =100 * noise(x/50.0, y/50.0);
stroke(co, 100, 100);
point(x, y);
}
}
}

最初に、setup()が呼ばれる。

  colorMode(HSB, 100);

が、カラーモード指定で、色をHue(色相)、Saturation(彩度)、 Brightness(明度)で表現し、範囲が0から100である。

draw() が実際に描画する部分だが、noise()関数は、引数を1個,2個,または3個とり、それぞれ1次元、2次元、3次元のnoize空間に対応する。引数に対しては、型はfloatで、範囲の指定は特にない。しかし、noise()の戻り値は0.0〜1.0となっている。
そのため、100倍して、HSBの色として利用している。
これを、ピクセル数だけ繰り返しているという、非常に単純なプログラムである。

のこのままでは、かなりぼやっとした感じなので、等高線のようなものを入れてみた。

PerlinNoise2.png

地図のような感じになってきた。
青が海で、緑が陸地で、山が黄色から橙色になっているとみなせるだろう。

色のmode 10 を計算し、整数化した時に0になる場合は、そのピクセルを黒にしただけである。

void setup() {
background(255);
colorMode(HSB, 100);
size(500, 500);
strokeWeight(1);
}

void draw() {
for ( int x=0; x<width; ++x ) {
for ( int y=0; y<height; ++y ) {
float co =100 * noise(x/50.0, y/50.0);
if ( int(co)%10 == 0 ) {
stroke(0, 0, 0);
} else {
stroke(co, 100, 100);
}
point(x, y);
}
}
}

最後に、3次元のnoise()関数を使って、時間と共に変化していく様を見てみよう。

PerlinNoiseMove.mp4

このプログラムは、noize()関数の第3引数に時間を加えただけであるので、説明は省略する。

float t = 100;

void setup() {
background(255);
colorMode(HSB, 100);
size(500, 500);
strokeWeight(1);
}

void draw() {
for ( int x=0; x<width; ++x ) {
for ( int y=0; y<height; ++y ) {
float co =100 * noise(x/50.0, y/50.0, t);
if ( int(co)%10 == 0 ) {
stroke(0, 0, 0);
} else {
stroke(co, 100, 100);
}
point(x, y);
}
}
t += 0.03;
}

noise()を、テクスチャに使うだけではもったいない。さまざまなデータの初期化とか、色々なことに使えそうである。