3Dをエンジンを作りたい(その2)

前回のコードから一部を修正したものがこちらになります。(修正部分周辺のみ載せます)

function project(v: Vertex): Point {
  return { x: v.x, y: v.y };
}

function render() {
  clear();
  cube.forEach(face => draw(
    project(face.v1),
    project(face.v2),
    project(face.v3),
  ));
  requestAnimationFrame(render);
}

projectというのは「投影」という意味で、3次元の点を2次元に投影しているわけですね。前回と同様に奥行きを捨てているだけです。

奥行きを考慮した描画にする

奥行きを考慮するというのは、要するに、カメラの位置から奥に(zが大きく)移動すれば移動するほど画面の中央に描画されるということです(消失点が画面中央にあれば)。それを踏まえて、奥行きを考慮した描画にしてみましょう。

// 箱の位置を微修正
const w = 10, h = 10, d = 10, p = { x: 0, y: 0, z: 50 };

// zが大きくなればなるほど、ratioが小さくなる
function project(v: Vertex): Point {
  const ratio = 200 / v.z;
  return { x: v.x * ratio, y: v.y * ratio };
}

奥行きがある

ご覧ください。奥行きがあります。奥のほうにある頂点は、より画面中央に寄っていますね。

まとめ

奥行きを考慮した描画にすると、とても迫力のある映像になりました。次は、カメラを移動できるようにしてみましょう。

以上です。よろしくお願いします。