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(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

rotateXrotateY は、回転する角度を受け取ります。角度にはラジアンという単位が使われますが、ここでは単位の計算を覚える必要はありません。frameCount0.01 のような小さな値を掛けると、時間とともに少しずつ回転します。0.010.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

translaterotate は、その後の描画座標へ影響します。push は現在の座標系を保存し、pop は元へ戻します。これがないと、1 つ目の移動と回転が 2 つ目の箱にも重なります。

translate(x, y, z) は、これから描くものの原点を移動します。最初の箱では x を -120 にして左へ、2つ目では x を 120 にして右へ移しています。y と z が 0 なので、上下と奥行きの位置は変わりません。

pushpop は、立体専用ではありません。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(70) は、全方向から当たる弱い光を置きます。directionalLight の最初の3つの数字は光の赤・緑・青、後ろの3つは光が進む向きです。最初は数字を暗記せず、色の3つの数字や向きの一つだけを変えて、どの面の明るさが変わるか観察します。

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

3D は計算負荷が高くなりやすく、端末によって滑らかさが違います。物体数を減らす、形を簡単にする、画面サイズを小さくするという調整は、作品の質を下げる作業ではありません。見せたい関係を残す編集です。

次章では、2D へ戻ってゲームを作ります。3D を通して見た座標変換と状態管理は、ゲームの画面設計にも使えます。

この章の小さな区切り

  • WEBGLを指定して箱を一つ表示できた
  • 回転、移動、光のどれか一つを変えた
  • 余裕があれば、正面版と斜め版を保存して見比べた

箱が一つ表示できれば、端末で動きが重くても保存して次章へ進めます。

参考資料