Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第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(ノーマル・マテリアル)は面の向きに応じて色を付けるため、光源をまだ設定していなくても立体の向きを観察しやすくなります。

濃紺の 500×400 のキャンバス中央に、正面を向いた青い箱が四角形のように見えている実行結果
図 17-1 正面からは奥の面が隠れ、箱が四角形のように見える。

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 つの数字や向きの一つだけを変えて、どの面の明るさが変わるか観察します。

黒い 500×400 のキャンバス中央でピンク色の箱が斜めに回転し、上面と側面の明るさが異なって見える実行結果
図 17-2 回転と光によって、正面では隠れていた複数の面が見える。

3D は計算負荷が高くなりやすく、端末によって滑らかさが違います。動きが重いときは、物体数を減らす、形を簡単にする、キャンバスを小さくする、の順に試します。回転や光の変化を残したまま、処理を軽くできます。

17.5 箱を展示物へ変える

箱を小さな展示物へ変えます。box(140) を box(60, 180, 60) へ変えると細長い柱に、box(180, 20, 120) へ変えると薄い板になります。box(ボックス)へ三つの数字を渡すと、幅、高さ、奥行きを別々に指定できます。まずどちらか一つだけ試します。

形の比率を確かめたあと、fill の三つの数字を変えると色も選べます。回転と光を残したまま、柱か板のどちらかを一つ保存します。次章では 2D へ戻り、キーで動かせる作品を作ります。

参考資料