こんにちは,れいじです. 少し間が開いてしまいました.
今日はジェネラティブアートのPart2,Chapter5を読みました.
Chapter5 次元を加える
Chapter4の最後でWaveClockを動かした時,これまでの例にはなかった時間という次元が加えられた.ジェネラティブアートを誰かに見せる時の媒体は決まって2次元(モニタ,紙,壁などなど)だけれど,どうすれば3次元のアートを表現することができるだろう?という感じの章.Processingの3次元描画を学びながら,アイデアを考え出していく.
ここでも重要になるのがパーリンノイズ. 前の記事では螺旋をぐにゃぐにゃにしたり,線を歪ませたりする所謂1次元のノイズを加えた.ここからは2次元のノイズを扱う.
2次元のノイズを使用したノイズグリッド.1次元のノイズが,真横から見た山脈のようであると表現するなら,2次元のノイズは真上から見た山脈(山脈と谷間からなる地形)のように見える. このノイズグリッドは描画の基本である点で絵を描いている.この点を四角に変更することで,また違ったノイズグリッドを描くことが出来た.
一目見た時ファミコンのドラクエみたいな地図を連想しました.面白いね. さらにパーリンノイズの生み出す値によって線の傾きを変更させると,このような波っぽい絵を描くことが出来た.
髪の毛のようにも見える. この3枚は背景を白にしているけど,逆に黒にして,パーリンノイズの影響を受ける図形を円に変更し,塗りつぶしのアルファ値を変更すると,飛行機から下を見下ろしたような,雲のような絵を描くことができた.
WaveClockを除いて,これまでのスケッチは全て静止画だった. これから本格的にアニメーションの描画の説明が始まっている.
float xstart, xnoise, ystart, ynoise; void setup() { size(300, 300); smooth(); background(0); frameRate(24); xstart = random(10); ystart = random(10); } void draw () { background(0); xstart += 0.01; ystart += 0.01; xnoise = xstart; ynoise = ystart; for (int y = 0; y <= height; y+=5) { ynoise += 0.1; xnoise = xstart; for (int x = 0; x <= width; x+=5) { xnoise += 0.1; drawPoint(x, y, noise(xnoise, ynoise)); } } } void drawPoint(float x, float y, float noiseFactor) { pushMatrix(); translate(x,y); rotate(noiseFactor * radians(540)); noStroke(); float edgeSize = noiseFactor * 35; float grey = 150 + (noiseFactor * 120); float alph = 150 + (noiseFactor * 120); fill(grey, alph); ellipse(0,0, edgeSize, edgeSize/2); popMatrix(); }
先ほどの雲のようなノイズにアニメーションを加えてみた.雲が流れているようなアニメーション.
次は流れるアニメーションにもノイズを加えてみる.
float xstart, xnoise, ystart, ynoise; float xstartNoise, ystartNoise; void setup() { size(300,300); smooth(); background(255); frameRate(24); xstartNoise = random(20); ystartNoise = random(20); xstart = random(10); ystart = random(10); } void draw () { background(255); xstartNoise += 0.01; ystartNoise += 0.01; xstart += (noise(xstartNoise) * 0.5) - 0.25; ystart += (noise(ystartNoise) * 0.5) - 0.25; xnoise = xstart; ynoise = ystart; for (int y = 0; y <= height; y+=5) { ynoise += 0.1; xnoise = xstart; for (int x = 0; x <= width; x+=5) { xnoise += 0.1; drawPoint(x, y, noise(xnoise, ynoise)); } } } void drawPoint(float x, float y, float noiseFactor) { pushMatrix(); translate(x,y); rotate(noiseFactor * radians(360)); stroke(0, 150); line(0,0,20,0); popMatrix(); }
なんか見てるとぞわぞわするアニメーションになった.この動きはWaveClockに似てる気がするな〜と思う.
アニメーションに触れた後に,ようやく3次元の描画に関する説明が始まった. Processingで3次元の物体を描く時は,OpenGLのインポートが必要らしい.
これはProcessingで描いた球体.球体はSphere関数で簡単に描くことができた.すごい.
3次元の描画を出来るようにすると,先ほど作った雲のアニメーションのノイズをまた違った視点で見ることが出来た.
import processing.opengl.*; float xstart, xnoise, ystart, ynoise; void setup() { size(500, 300, OPENGL); background(0); sphereDetail(8); noStroke(); xstart = random(10); ystart = random(10); } void draw () { background(0); xstart += 0.01; ystart += 0.01; xnoise = xstart; ynoise = ystart; for (int y = 0; y <= height; y+=5) { ynoise += 0.1; xnoise = xstart; for (int x = 0; x <= width; x+=5) { xnoise += 0.1; drawPoint(x, y, noise(xnoise, ynoise)); } } } void drawPoint(float x, float y, float noiseFactor) { pushMatrix(); translate(x, 250 - y, -y); float sphereSize = noiseFactor * 35; float grey = 150 + (noiseFactor * 120); float alph = 150 + (noiseFactor * 120); fill(grey, alph); sphere(sphereSize); popMatrix(); }
本当に飛行機に乗っているみたい!すごい.
パーリンノイズを描けるnoise関数は3つまで引数を指定することができ,最高3次元のノイズを生み出すことが出来るらしい.
これを使用すれば,先ほどの雲や,或いは煙のようなノイズを表現できる.
float xstart, ystart, zstart; float xnoise, ynoise, znoise; int sideLength = 200; int spacing = 5; void setup() { size(500, 300, P3D); background(0); noStroke(); xstart = random(10); ystart = random(10); zstart = random(10); } void draw () { background(0); xstart += 0.01; ystart += 0.01; zstart += 0.01; xnoise = xstart; ynoise = ystart; znoise = zstart; translate(150,20,-150); rotateZ(frameCount * 0.1); rotateY(frameCount * 0.1); for (int z = 0; z <= sideLength; z+=spacing) { znoise += 0.1; ynoise = ystart; for (int y = 0; y <= sideLength; y+=spacing) { ynoise += 0.1; xnoise = xstart; for (int x = 0; x <= sideLength; x+=spacing) { xnoise += 0.1; drawPoint(x, y, z, noise(xnoise, ynoise, znoise)); } } } } void drawPoint(float x, float y, float z, float noiseFactor) { pushMatrix(); translate(x, y, z); float grey = noiseFactor * 255; fill(grey, 10); box(spacing, spacing, spacing); popMatrix(); }
煙が充満している立方体がぐるぐる回っているように見える.
実際は箱のなかに煙があるわけではなくて,立法体の色をノイズによって指定しているだけ.発想の転換だなぁ.
3次元の描画を使えば,前記事で描いた螺旋だっておもしろいアートになる.
import processing.opengl.*; int radius = 100; void setup() { size(500, 300, OPENGL); background(255); stroke(0); } void draw() { background(255); translate(width/2, height/2, 0); rotateY(frameCount * 0.03); rotateX(frameCount * 0.04); float s = 0; float t = 0; float lastx = 0; float lasty = 0; float lastz = 0; while (t < 180) { s += 18; t += 1; float radianS = radians(s); float radianT = radians(t); float thisx = 0 + (radius * cos(radianS) * sin(radianT)); float thisy = 0 + (radius * sin(radianS) * sin(radianT)); float thisz = 0 + (radius * cos(radianT)); if (lastx != 0) { line(thisx, thisy, thisz, lastx, lasty, lastz); } lastx = thisx; lasty = thisy; lastz = thisz; } }
Part2は最初から最後まで乱数やパーリンノイズを使用したアートの紹介とProcessingの勉強を行ってきた.
というより,どちらかというとまだまだProcessingの基礎から抜け切れていない内容だったと思う.
コードを動かして,Processingでできる表現の幅を増やして,予測不可能性とは何なのか,そしてそれを実現するための方法は何があるかといった知識をつけていった.でもまあ,最初から最後までこの乱数とかパーリンノイズは出てくるんだろうなあ.
次はPart3,創造性というタイトルが付いてます. 中身をパラパラとめくった感じだと,アートに繋がるような,チュートリアルから抜ける実践的な表現を紹介していくっぽい.
楽しみです.ではでは!