第17章 3D は座標を一つ増やした舞台
2D では x と y で位置を決めました。3D では奥行きの z が加わります。ただし、立体の命令を使っただけで奥行きが伝わるわけではありません。回転、光、手前と奥の重なりによって、平らな画面へ空間を感じさせます。
17.1 WEBGL で原点が中央へ移る
def setup
createCanvas(500, 400, WEBGL)
end
def draw
background(25, 30, 48)
normalMaterial
box(120)
end
WEBGL を指定すると 3D 描画モードになります。2D の既定では原点が左上でしたが、WEBGL モードでは原点がキャンバス中央です。第2章の座標感覚をそのまま使うと、位置がずれて見えます。
box(ボックス)は箱を描きます。box(120) なら幅、高さ、奥行きが同じです。normalMaterial(ノーマル・マテリアル)は面の向きに応じて色を付けるため、光源をまだ設定していなくても立体の向きを観察しやすくなります。
17.2 回転しなければ箱は四角に見える
正面から箱を見ると、奥の面が手前に隠れ、四角形のように見えることがあります。x 軸と y 軸の周りに回転します。次の draw は変更部分です。17.1 のコードにある def draw から対応する end までと置き換えます。
def draw
background(25, 30, 48)
normalMaterial
rotateX(frameCount * 0.01)
rotateY(frameCount * 0.013)
box(120)
end
rotateX(ローテート・エックス)と rotateY(ローテート・ワイ)は、回転する角度を受け取ります。角度にはラジアンという単位が使われます。この章では、画面の回転から値の違いを確かめます。frameCount に 0.01 のような小さな値を掛けると、時間とともに少しずつ回転します。0.01 を 0.03 へ変えると回転が速くなります。
17.3 push と pop で座標変換を閉じ込める
2 つの箱を別々に動かします。次の draw も変更部分で、直前の draw 全体と置き換えます。
def draw
background(25, 30, 48)
normalMaterial
push
translate(-120, 0, 0)
rotateY(frameCount * 0.02)
box(80)
pop
push
translate(120, 0, 0)
rotateX(frameCount * 0.015)
box(80)
pop
end
translate(トランスレート)や rotate(ローテート)は、その後の描画座標へ影響します。push(プッシュ)は現在の座標系を保存し、pop(ポップ)は元へ戻します。これがないと、1 つ目の移動と回転が 2 つ目の箱にも重なります。
translate(x, y, z) は、これから描くものの原点を移動します。最初の箱では x を -120 にして左へ、2 つ目では x を 120 にして右へ移しています。y と z が 0 なので、上下と奥行きの位置は変わりません。
push と pop は、立体専用ではありません。2D の回転や拡大縮小でも、変換の影響範囲を分けるために使えます。
17.4 光が形の読み方を変える
normalMaterial を外し、光を置きます。次の draw も変更部分で、直前の draw 全体と置き換えます。
def draw
background(20)
ambientLight(70)
directionalLight(255, 240, 220, -1, 0.5, -1)
noStroke
fill(235, 90, 120)
rotateX(frameCount * 0.01)
rotateY(frameCount * 0.013)
box(140)
end
環境光は全体を弱く照らし、平行光源は一定方向から照らします。同じ箱でも、明暗によって面の向きが読みやすくなります。
ambientLight(アンビエント・ライト)は全方向から当たる光、directionalLight(ディレクショナル・ライト)は一方向から当たる光を置きます。directionalLight の最初の 3 つの数字は光の赤・緑・青、後ろの 3 つは光が進む向きです。最初は数字を暗記せず、色の 3 つの数字や向きの一つだけを変えて、どの面の明るさが変わるか観察します。
3D は計算負荷が高くなりやすく、端末によって滑らかさが違います。動きが重いときは、物体数を減らす、形を簡単にする、キャンバスを小さくする、の順に試します。回転や光の変化を残したまま、処理を軽くできます。
17.5 箱を展示物へ変える
箱を小さな展示物へ変えます。box(140) を box(60, 180, 60) へ変えると細長い柱に、box(180, 20, 120) へ変えると薄い板になります。box(ボックス)へ三つの数字を渡すと、幅、高さ、奥行きを別々に指定できます。まずどちらか一つだけ試します。
形の比率を確かめたあと、fill の三つの数字を変えると色も選べます。回転と光を残したまま、柱か板のどちらかを一つ保存します。次章では 2D へ戻り、キーで動かせる作品を作ります。
参考資料
- rbCanvas/p5 0.5.1 概要 — 3D 描画を含む対応範囲と実行環境
- rbCanvas/p5 0.5.1 API リファレンス —
WEBGL、box、回転、光の仕様 - p5.js WebGL チュートリアル — 座標変換の概念。サンプルは JavaScript で書かれている