Open18
2023.12.9 Colorful Hackathon講演メモ
表現するプログラミング ジェネラティブアートへ入門
by GINさん
ジェネラティブアートとは
- 偶発性を取り入れたプログラム(アルゴリズム)により、コンピュータ(Web上)で生成されるアート
- 実行するたびに描画される結果が変わるのが特徴
作例
Okazzさん
takawoさん
- 今日使うプログラミング言語:JavaScript
- JavaScriptを使った絵を描くことに特化したプログラミング開発環境:p5.js
p5.jsのいいところ:Web上で作品作りが完結する
p5.jsのWebエディタ
- OpenProcessing
- https://openprocessing.org/
まずは丸を描く
function setup() {
// キャンバスを用意
createCanvas(500, 500);
// 背景を設定
background(230);
// 円を描く
ellipse(250, 250, 100); // 横の位置, 縦の位置, 円の大きさ
}
)
色の指定
RGBで指定
赤・緑・青の順で、0~255の数値で指定。全て0だと黒になり、255だと白になる
fill(255, 0, 0);
数字一つで指定
白黒の指定。0~255。0が黒、255が白
fill(255)
カラーコードで指定
fill('#ff0000')
Googleでカラーピッカーと検索すれば、RGBやカラーコードを簡単に調べられる
function setup() {
createCanvas(500, 500);
background(230);
// 枠線の色
stroke(0, 0, 255);
// 枠線の線幅
strokeWeight(10);
// 図形の塗りつぶし色
fill('#ff0000');
ellipse(200, 300, 300);
}
原点を動かす
function setup() {
createCanvas(500, 500);
background(230);
// キャンバスの中心に原点を移動
translate(250, 250);
ellipse(0, 0, 100); // キャンバスの中心に円を描画
ellipse(100, 100, 100); // 中心から右上に円を描画
ellipse(-100, -100, 100); // 中心から左下に円を描画
}
クマを描く
顔の形をつける
function setup() {
createCanvas(500, 500);
background('#ffd8c8');
translate(250, 250);
// 枠線は描かない
noStroke();
// 顔の色
fill('#a06030');
// 顔を描く(耳を後でつけるので少し下に)
ellipse(0, 10, 200, 150); // 4つ数字を指定すると、最後の2つで円の横の大きさと縦の大きさを指定できる
}
透明度の指定
fill(250, 0, 0, 160)
- (赤, 緑, 青, 透明度)で指定
- 0が透明、255が不透明
fill(250, 160)
- (白黒, 透明度)で指定
- 0が透明、255が不透明
fill('#ff0000b0')
- カラーコードに続けて指定(
b0
の部分。b0
は約69%) - 00が透明、ffが不透明
クマを描く
完成
function setup() {
createCanvas(500, 500);
background('#ffd8c8');
translate(250, 250);
// 枠線は描かない
noStroke();
// 顔の色
fill('#a06030');
// 顔
ellipse(0, 10, 200, 150); // 4つ数字を指定すると、最後の2つで円の横の大きさと縦の大きさを指定できる
// 耳
ellipse(60, -50, 80);
ellipse(-60, -50, 80);
// 目
fill(0);
ellipse(50, -15, 15, 10);
ellipse(-50, -15, 15, 10);
// 鼻の周り
fill('#ffffff80'); // RGBのカラーコードに加えて透明度を指定
ellipse(0, 50, 100, 70);
// 鼻
fill(0);
ellipse(0, 20, 15, 10);
}
ジェネラティブアート・ライブコーディング
by takawoさん
アジェンダ的なもの
- アルゴリズム(ある規則)とそれを用いた作品化へのプロセスの紹介
- ランダムの利用方法
- カラーパレットの作り方
- 色の選び方
- 画面構成
- 関数:省略詠唱でコードを呼び出す
- アイディアの構成化
作品を考えるためのアプローチ
- システムを作ってそれが美しい
- 作家性の感じる個性をコードに取り込む
- e.g. qubibiというアーティスト
- コンセプトを作品の中に入れる
今回のアプローチは?
今回はアルゴリズムを基礎として表現に取り込んで、それを元に作品を作ってみる
10PRINTという斜線の組み合わせで絵を描けるみたいなものをやる
右肩上がりと右肩下がりの線の格子がランダムに組み合わさっていて美しいみたいな作品を作ってみる
画面構成の工夫
ある時期の作品では画面の中に図形を収めていたが、いまでは窮屈だと感じる。はみ出そう・斜めにしようとか取り入れていくと、個性が出てくる。
画面幅に対して収めるのではなく、少しはみ出すようにしたり、
let cells = int(random(3, 8)) * 5;
let d = width * 1.2 / cells;
キャンバス全体を回転させてみたり。
push();
transalte(width/2, height/2);
rotate(45);
transalte(width/2, height/2);
for (...) {
...
}
pop();
というアイディアを取り入れてみる。
三平方の定理で画面の対角線の長さを計算して、その長さを基準に絵を描くと、画面いっぱいに使うことができる
let w = sqrt(sq(width), sq(width));
push();
transalte(width/2, height/2);
rotate(45);
translate(-w/2, -w/2); // 最初のtranslateで描画する領域が右下にずれてしまったのを、対角線の長さを使って絵を戻す
...
pop();
p5-brushを使うと絵筆のテクスチャで描画できる
線を自分好みに引けるようにする
function drawOriginalLine(x1, y1, x2, y2) {
let distance = dist(x1, y1, x2, y2); // 2点間の距離を計算
let angle = atan2(y2-y1, x2-x1); // 2点間の角度を計算
push();
translate(x1, y1); // 基準となる線に移動する。何度の角度でどのくらい移動するかを定義すれば線を描ける
rotate(angle);
line(0, 0, distance, 0); // ここを書き換えれば、線をどう描くかを好きにカスタマイズできる
pop();
}
例えば、
うねうねした螺旋を描きながら線を描画する
function drawOriginalLine(x1, y1, x2, y2) {
let distance = dist(x1, y1, x2, y2); // 2点間の距離を計算
let angle = atan2(y2-y1, x2-x1); // 2点間の角度を計算
push();
translate(x1, y1); // 基準となる線に移動する。何度の角度でどのくらい移動するかを定義すれば線を描ける
rotate(angle);
let x = 0;
while(n < distance) {
stroke(0, 0, 10);
push();
translate(x, 0); // ずらしながら
rotate(x); // 回転しながら
circle(0, 0, x/2, x/y); // 楕円を描画
pop();
x++;
}
pop();
}
ノイズを使ってさらに変化をつける
function drawOriginalLine(x1, y1, x2, y2) {
let distance = dist(x1, y1, x2, y2); // 2点間の距離を計算
let angle = atan2(y2-y1, x2-x1); // 2点間の角度を計算
push();
translate(x1, y1);
rotate(angle);
let x = 0;
while(n < distance) {
stroke(0, 0, 10);
push();
translate(x, 0);
let n = noise(x1, y1, x/distance); // ノイズを作って
rotate(x+n*360); // 回転にノイズを絡める
circle(0, 0, x/2, x/y);
pop();
x++;
}
pop();
}
パレットの作り方
- e.g. Marching Resonances
- https://www.brightmoments.io/quarterly/takawo
- 設置する場所で使われている色を取ったり、日本の伝統的な配色を取り入れたりした
- 画像サイト(https://unsplash.com )から好みに合う画像を引っ張ってきてそれを材料にする
- Adobe Colorなどで画像からカラーパレットを作成する
パレットの使い方
パレットからランダムに取り出す
const palette = ['#ff0000', '#00ff00', '#0000ff'];
const color = random(palette);
パレット配列をコピーして、シャッフルする
const = ['#ff0000', '#00ff00', '#0000ff'];
const colors = shuffle(palette.concat());
線形補間を使って、色と色の中間色を計算する
const from = color(colors[0]); // lerpColorを使うにはColorインスタンスが必要
const to = color(colors[1]);
const interA = lerpColor(from, to, 0.33); // 33%地点の色
const interB = lerpColor(from, to, 0.66); // 66%地点の色
↑の作品では、他にもいろいろ工夫してる。
- shearを使って形を歪ませる
- shearX
- shearY
- 例えば歪な楕円形・菱形を作れる
-
blendMode(BURN)
で焼き込みをつける - シャドウブラーをつける
drawingContext.shadowBlur = width / 15;
ライブコーディング見ながら思ったこと
- 予測できるパターンと予測できないランダム性のバランスを取りながら作品を作っていく
- その中に独創的なアイディアや個性を加えていくことで、自分だけの作品として仕上がっていく
- 補足
- 「予測できるパターン」は作品全体の軸になるが、作品の面白さになるのはランダム性
- 作品の軸になるパターンは意識的に選び、それ以外で予測可能な要素はなるべく排除する
- 逆に、全てが予測できない作品は見る人に理解するための取っ掛かりを与えられない
コレクター×アーティスト トーク
Pochitaさんコレクション紹介
Perpendicular Inhabitation
- ドバイの人だけど日本文化が大好き
- 日本のバブル期のシティポップをインスパイアした作品
- Plette Typeにも日本の名前が現れている(アーティスト名や知名?)
C-SCAPE
- ミントされるごとに初期値が決まるので、自分のものは必ず同じものが出てくるようになっている
- コレクターがミントするときにアウトプットに関与するのもジェネラティブアートならでは
- 好きなアウトプットとそうではないアウトプットが出てくるのはデメリットでもある
DOM1
- 音楽と一緒に生成されていく
- Webブラウザならではの表現を追求している
- その場でdiv要素を生成して、ページが下に伸びていく
hasaquiさん作品紹介
MOUNTAINS
- 線画かっちりした作品が主流だった頃に、もうちょっとぼやっとしたような朽ちていくような、日本的な表現ができないかと思ってやった
- オンチェーンに固定化されると朽ちていくみたいな表現ができないかと思って
- 自分がフラックスと呼んでいる技法を使っている。三角形をいっぱい配置して、その上で崩していく処理をしている、ランダムにコピーしてペーストしていく処理をやっている
- いい表現のできるアルゴリズムができたと思ったらそれを軸にいろいろ作る。それをシリーズとして作っていて、効率的な作品にもなる。アルゴリズムにコンセプトを載せるというのができると説明もしやすい
◉◉◉
- ランダムに動くウォーカーで円を描画している
- 丸がだんだん小さくなっていくことでキャンバスの布地のようになっていく
- 色によって背面にいくか前面にいくかを制御している
YANAARISU
- ベースになっているのは◉◉◉と同じ
- 円だったものをベジェ曲線にしている
- 花にしたかったので、RGMのGが一定量を超えた時に下に垂れていくようにした(花の茎)
- 画面上にあるものは全て制御可能なので、パラメータチューニングでいろいろなバリエーションを試してみて後でとっておく
ジェネラティブアートの面白さ
- ブラウザで見るだけでなく、最終的なアウトプットはフィジカルというものも増えている。そういうものが増えていくのではないかと思っている(Pochitaさん)
- fxhashでも、ミントした後にプロッターでプリントしたものを届けてくれるものがある
- マイアミのイベント?では、プロッターで油絵の具をつけて3ETHで売るというのもあった
- 作家によっては高値で売りつつ、タダだったり0.1TEZOSで売ったりという人もいる(hasaquiさん)
- ハイとロウが出てくるのではないか
- イーサだとコード量によってはガス代で4万円とかかかることもあるなか、どうなっていくかは楽しみ
- ガス代を気にすることなく作品作りができ、表現の幅が広いのがfxhash・TEZOSチェーンのいいところ(Pochitaさん)
- イーサの人が入ってきてなんかいいのあるじゃんとなったら、TEZOSでの価値も上がっていくかもしれない
ykxotkxさん × takawoさん パネルディスカッション
takawoさん→ykさん
- どういうふうに作風が固まっていった?
- 最初はいろいろなものを作っていた
- 浮世絵の作品を作るときに、それまでの作品と違ってそれなりの期間をかけて作り込んだ。ジェネラティブアートというと抽象的なものが多く具象的な風景をジェネラティブアートの技法を使って作ったら面白いかもしれないと思って作った
- その後、具象的なものをジェネラティブアートの技法で作るという作品をいくつか繰り返していった
- 制作過程をシェアしていた時のウケも良くて嬉しかったのでそれを突き詰めてみようと思った
- 感覚的に作るのではなく設計したりアウトプットを定めていったりする労力がかかるのではないかと思うが、そういうコストは変わってきている?
- そこは変わってきている
- コードのサイズが大きくなりがち
- 浮世絵風の作品から大きくなっていって、Traveler・Flower Arrangement・Stargaserではかなりコード規模が大きい
- オンチェーンでやろうとすると莫大なコストがかかると思う
Traveler
- SF風の仮装絵的な風景を描いた
- 描画に時間がかかるのでローディングの画面を入れてある
- どういうことを考えて作った?
- 作りたい・表現したい主題や世界観をイメージして、その段階では手でスケッチしたりしている。それをコードに落とし込んでいくにはどういうテクニックを使えばいいかを考えながら作っている
- この作品にはバリエーションもある
- どれも共通してSFの世界の風景を描いたが、バリエーションとしては両側に崖があって沼地に囲まれた風景があったり、海の上に都市が浮遊していたり、洞窟の中だったり、景色のバリエーションを持たせている
- ここまでのいろいろな風景を含めながら作っていくのは尋常じゃない工程が伺える
- そこはソフトウェア開発者の経験が役に立っている
- テストを回してから出すとか
- 160パターン自動で生成するようなスクリプトを書いている
- 解像度を変えても崩れないようにするとか
- ブラウザがChromeとかFirefoxとかiPhoneでも動くようにしているとか
- それを苦にせずできるのはソフトウェア開発の経験のおかげ
- そこはソフトウェア開発者の経験が役に立っている
大切にしていること
- 作品作りで大切にしているものはあるか?
- コードで描いているけどそうは見えない手描き感・緻密さを持たせるようにしている
- Bright Momentで選んでもらったときに、その理由として「世界観がから」と言ってもらえた。世界観がしっかりしていてわかりやすくするようにしている
- まだ表現を高める余地はある?
- 星空の質感を出すときに、ペタッとしたものにならないように実際の星空の濃淡が出るように・油絵で描いたみたいになるように、コードでどう描くかを探すというのは作品ごとに課題・挑戦ポイントが出てくる
- それはまだ新しい作品を作るごとにあると思う。突き詰めたとは思っていない
- どこまでやったら完成と捉えている?
- 自分の中で完成形をイメージしてそれをコードで再現していくということが多いので、自分の中の完成形に十分近づいた時が完成
- 偶発的に面白い質感や結果が得られることもある。それを得られたらそれを活用できるように完成形を変えていくこともある
企業依頼のプロジェクト
- MoMAプロジェクト
- MoMAのポストカードプロジェクト(Web3の技術を使った社会実験的な側面がある。15個スタンプを押せるスタンプカードを回していく)
- Web3で活動している15人のアーティストにポストカードのための作品制作が依頼された。それに選んでもらった
- 個人発表の作品だけでなく企業に依頼されて制作する作品も出てくる中で意識が変わったことはあるか?
- Bright Moment(サントリーとのコラボ)で、お題に合わせて作るのは初めてだった。ちょっと苦戦するところはあった。納期が決まっているのも大きい。それに合わせて作り込むのはプレッシャーのかかる作業だった
- MoMAのプロジェクトは初めて他のアーティストと一緒に作る作品だったので、アーティストごとに自分の個性・価値観を持っている人たちとのコラボレーションの中で自分の個性ってなんだろうと見つめ直す機会になった
質問タイム
- ラフを描いてからやるのか、緻密なものを作ってからやるのか(sakamuraさん)
- 自分の中にある完成形を目指して、本当に作れるのかから始まっていく
- 世界観に近いコードのアウトプットが出てきたら、そこからバリエーションを考えていく
- 思ったらうまくいかないこともしょっちゅうあるので、コードを書きながら完成図を調整していくことはしばしばある
- どういうところからインスピレーションを得る?
- 例えばFlower Arrangementhは?スケール的に「部屋の中」といういつもとは違う印象を感じた(takawoさん)
- 技術先行で、Travelerの制作中に丸いモチーフをサークルパッキングという技法を使っていて、それに合ったモチーフとしてフラワーアレンジメントを作ってみたら面白いものができた。2週間くらいでできちゃった。
- 植物をよりリアルに見せるために、花の向きが自然に見えるようにした。下のものは垂れ下がっていて、上のものはピンとなるように。ベジェ曲線を使ってどうしたらリアルに見えるだろうと楽しみながら作った
- 静物画っぽいテイストになるようにした
- 例えばFlower Arrangementhは?スケール的に「部屋の中」といういつもとは違う印象を感じた(takawoさん)
- 日本のクリエイティブコーダーでここまでしている人って少ない。Featuresを活かしてバリエーションを出す技法が知れ渡っていない。どうすればいいとかある?(takawoさん)
- Featuresやバリエーションの決め方は作品による。突き詰めて考えたことはない。他の人の作品を見ながら参考にしている