p5.js WebGLモードで深める空間の詩学:光と影が織りなす存在の問い
2Dの平坦なキャンバスに慣れ親しんだ私たちが、次なる表現の地平として3D空間に足を踏み入れるとき、何を求めるのでしょうか。それは、単にオブジェクトを配置する以上の、もっと根源的な欲求ではないでしょうか。そこに生まれる奥行き、光と影の交錯、そして鑑賞者の視線そのものをデザインしたいという渇望です。本稿では、p5.js の WebGL モードを使い、3D空間における詩的な表現、つまり「空間の詩」を紡ぐための思考の断片を探求します。形状、視点、光、そして時間が織りなす存在の問いへと、共に旅を始めましょう。
三次元空間への扉を開く:p5.jsのWEBGLモード入門
p5.jsで三次元の世界への扉を開くのは、驚くほど簡単です。createCanvas() 関数の第3引数に WEBGL を指定する、ただそれだけです。しかし、この一行がもたらすのは、単なるレンダリングモードの切り替えではありません。それは、私たちの制作における思考のパラダイムシフトを意味します。これまで左上を原点 (0, 0) としていた二次元の座標系から、キャンバスの中央を原点 (0, 0, 0) とする三次元のデカルト座標系へと、私たちの認識が再構築されるのです。
function setup() {
// 第3引数に WEBGL を指定する
createCanvas(windowWidth, windowHeight, WEBGL);
}
function draw() {
background(0);
// X軸とY軸を中心にフレームごとに回転させる
rotateX(frameCount * 0.01);
rotateY(frameCount * 0.01);
// 辺の長さが100の立方体を描画
box(100);
}
この短いスケッチを実行した瞬間、私たちはZ軸という新しい次元の存在を直感的に理解します。静的な画像ではなく、回転する立体として現れる box() は、奥行きという概念を雄弁に物語ります。WEBGL モードは、ブラウザが持つグラフィックスハードウェアの能力 (WebGL API) を直接利用するため、2Dのデフォルトレンダラー (P2D) よりも遥かに高速な描画が可能です。ただし、一部の関数、例えば rect() の引数の解釈などが2Dモードと異なる点には注意が必要です。この座標系の変化こそが、空間表現 への第一歩となります。
プリミティブ形状が語る物語:幾何学的な詩の創造
p5.jsの3D空間では、box() (立方体)、sphere() (球体)、cylinder() (円柱)、torus() (トーラス) といった基本的な幾何学的形状、すなわちプリミティブ形状を自在に呼び出すことができます。これらは単なる作図のための部品ではありません。一つ一つが独自の意味と象徴性を帯びた、詩を構成するための語彙です。立方体は秩序と安定を、球体は完全性と無限を、トーラスは循環と連続性を想起させます。
これらのプリミティブ形状を、ジェネラティブなアルゴリズムによって配置し、変形させることで、無機質な幾何学から有機的な生命の営みや、混沌とした風景を編み上げることが可能になります。例えば、無数の球体をランダムに、しかし何らかの規則性(例えばパーリンノイズ)に従って配置し、その大きさを時間とともに変化させるだけで、あたかも宇宙の星々が瞬いているかのような、あるいは深海のプランクトンが漂っているかのような情景が生まれます。
function draw() {
background(20);
noStroke();
lights(); // 立体感を出すために光源を配置
for (let i = 0; i < 50; i++) {
push(); // 現在の座標系を保存
translate(
random(-200, 200),
random(-200, 200),
random(-200, 200)
);
rotateX(random(TWO_PI));
rotateY(random(TWO_PI));
// sin波でサイズを滑らかに変化させる
let size = sin(frameCount * 0.01 + i * 0.1) * 30 + 30;
sphere(size);
pop(); // 座標系を元に戻す
}
}
このプロセスにおいて、push() と pop() の役割は極めて重要です。これらは座標系の状態(移動、回転、拡大縮小)をスタックに一時保存し、また復元する機能を提供します。これにより、個々のオブジェクトに独立した変換を適用し、他のオブジェクトに影響を及ぼすことなく、複雑なシーンを構築できます。一つ一つの形状が、それ自身の物語を語り始めるのです。
視点と遠近法:鑑賞者の眼差しをデザインする
3D空間における表現の核は、その世界をどこから、どのように「見る」かという視点の設計にあります。カメラを制御することは、すなわち鑑賞者の体験そのものを演出することに他なりません。p5.jsは、この演出のための強力なツールを提供します。その中心となるのが camera() 関数と perspective() 関数です。
camera() 関数は、カメラの位置、そのカメラが向いている注視点、そしてカメラの上方向を定義します。これにより、対象を遥か上空から見下ろす俯瞰の視点や、足元から見上げるような視点、あるいは対象の周りを滑らかに回り込むような視点を自由に作り出すことができます。一方、perspective() 関数は、遠近法がどのように作用するかを調整します。視野角を広げれば空間の歪みが強調された広角レンズのような効果が、狭めれば遠くのものを引き寄せる望遠レンズのような効果が得られます。
function draw() {
background(0);
// マウスのX座標に応じて、カメラが原点の周りを水平に旋回する
let camRadius = 400;
let camAngle = map(mouseX, 0, width, 0, TWO_PI);
let camX = cos(camAngle) * camRadius;
let camZ = sin(camAngle) * camRadius;
// camera(目のX, Y, Z, 中心のX, Y, Z, 上方向のX, Y, Z)
camera(camX, 0, camZ, 0, 0, 0, 0, 1, 0);
box(150);
}
このインタラクティブなカメラ制御は、鑑賞者を単なる傍観者から、能動的な探索者へと変えます。鑑賞者自身の操作によって作品の様相が変化するとき、作品と鑑賞者の間には対話が生まれます。しかし、過度なカメラワークは鑑賞者に混乱や不快感を与える可能性もあります。静的な視点がもたらす瞑想的な時間と、動的な視点がもたらす発見の喜び。どちらが作品の意図を最も深く伝えるのかを熟考することが、クリエイティブコーディング における重要なデザイン的決断となるのです。
光と影の戯れ:マテリアルとライトで空間に息吹を
形あるもの全てが光を受け、影を落とす。この自明の理をデジタル空間で再現することによって、単なる形状の集合は、質量と実在感を持つ風景へと変貌します。p5.jsの WebGL モードでは、光源 (lights) と物体の表面特性であるマテリアル (materials) を定義することで、この繊細な光と影の戯れを演出できます。
光源にはいくつかの種類があります。空間全体を均一に照らす環境光 (ambientLight)、太陽光のように一方向から降り注ぐ平行光源 (directionalLight)、そして電球のように一点から放射状に広がる点光源 (pointLight) などです。これらの光源を組み合わせることで、柔らかい朝の光や、強いコントラストを生む真昼の光、あるいは複数の光源が交錯するドラマチックな夜のシーンを作り出せます。
そして、その光をオブジェクトがどのように反射するのかを決定するのがマテリアルです。光沢のある表面を表現する specularMaterial、マットな質感の ambientMaterial、あるいは面の向き自体を色で表現し、デバッグや幾何学的な表現に役立つ normalMaterial などがあります。
function draw() {
background(10);
noStroke();
// 右上から青みがかった平行光源を当てる
directionalLight(0, 150, 255, 0.5, -1, -0.5);
// 全体に弱く赤い環境光を追加する
ambientLight(60, 0, 0);
rotateY(frameCount * 0.01);
push();
// 光沢のある白いマテリアル
specularMaterial(250);
sphere(80);
pop();
push();
translate(200, 0, 0);
// 法線マテリアル
normalMaterial();
torus(60, 20);
pop();
}
光とマテリアルの選択は、空間のムードを決定づける、極めて詩的な作業です。同じ形状であっても、当たる光の色や角度、表面の質感が変わるだけで、冷たい金属にも、温かい石にも、あるいは未知の生命体にも見えます。この光の設計こそが、空間に深みと感情を与える鍵なのです。
動きと時間:3Dアニメーションの哲学
3D空間に「時間」という四次元目の軸を導入したとき、静的な彫刻は生命を宿したパフォーマンスへと変容します。アニメーションとは、単にオブジェクトを動かす技術ではありません。それは、生成と消滅、成長と衰退、あるいは永遠の反復といった時間的な構造を、空間に織り込む行為です。p5.jsでは、frameCount や millis() といった時間変数と、translate() や rotate() などの変換関数を組み合わせることで、この時間軸を操ることができます。
三角関数 (sin(), cos()) を用いれば、惑星の公転や振り子のような、滑らかで周期的な動きを生み出すことができます。一方、パーリンノイズ (noise()) を用いれば、風に揺れる木の葉や、水面のきらめきのような、より有機的で予測不可能な動きを表現できます。これらの動きを個々のオブジェクトに与えることで、静止したシーンは躍動感あふれる世界へと変わります。
// パーティクルクラスの update メソッドの例
class Particle {
// ... constructorやdisplayなど ...
update() {
// 時間の経過(t)と各個体のオフセットを使い、ノイズから位置を生成
let t = frameCount * 0.001;
let noiseScale = 0.005;
this.pos.x = map(noise(this.offset.x + t), 0, 1, -width/2, width/2);
this.pos.y = map(noise(this.offset.y + t), 0, 1, -height/2, height/2);
this.pos.z = map(noise(this.offset.z + t), 0, 1, -300, 300);
}
}
3Dアニメーションは、空間における存在のあり方を問い直します。その動きは永遠に続くのか、それともいつか終わりを迎えるのか。鑑賞者のインタラクションによって、その運命は変わるのか。時間の流れをどのようにデザインするかという選択が、作品の物語性と哲学的深度を決定づけるのです。
空間が問いかけるもの:ジェネラティブ3Dアートの深淵
ここまで探求してきた形状、視点、光、そして時間を、ジェネラティブアート のアルゴリズムと組み合わせることで、私たちの創造は作者自身の意図すら超えた領域へと至ります。3D空間は、もはや単なる描画のためのキャンバスではありません。それは、自律的なシステムが生まれ、進化し、そして消滅する仮想の生態系、あるいは思考実験の場となるのです。
もし、2Dのジェネラティブアートが「平面における構成」の探求であるならば、3Dのそれは「空間における関係性」の探求と言えるかもしれません。オブジェクト同士の距離や位置関係、オブジェクトと光源の関係、そしてオブジェクトと鑑賞者(カメラ)の関係。これらの無数に存在する関係性の網の目の中に、作者も予期しなかった美や秩序、あるいは混沌が自発的に立ち現れる瞬間があります。フラクタルやL-Systemのような再帰的なルールを三次元で展開すれば、仮想の植物が成長する様を、エージェントベースモデルを実装すれば、鳥の群れ (Boids) が意思を持つかのように空間を舞う様をシミュレートできます。
p5.jsが提供する p5.js 3D の世界は、単にZ軸を追加する技術的なステップに留まりません。それは、私たちが普段認識しているこの三次元世界を、コードという純粋な論理言語で再解釈し、再構築するための、広大で深遠な思考のフレームワークです。その仮想空間に光を当て、視点を与え、時間を流し込むことで、私たちは「存在とは何か」「生命とは何か」という根源的な問いを、ディスプレイという窓の中に静かに立ち上げることができるのです。


