Intro - mattdesl/cam3d GitHub Wiki

Currently there are plenty of 3D JavaScript frameworks for dealing with WebGL and CSS3D transforms, but not as many that focus on using 3D graphics in 2D canvas applications. The cam3d and vecmath modules provide the basis for getting a simple 3D scene up and running with Canvas rendering. They are generic enough that they can be used with any renderer, including WebGL or DOM, and may also be useful to those working on projects with PIXI, Enchant.js, EaselJS, etc.

THREE.js is an awesome library, and its CanvasRenderer is ideal if you need to draw a triangle-based 3D scene using imported models, texture mapping, depth-sorting, and so forth.

However, the THREE.js CanvasRenderer is mainly aimed at emulating its WebGL renderer. It does not give you fine control over line style (join, caps, etc), gradient fills, clipping regions, compositing layered canvases, per-pixel canvas modifications, and so forth. Often you may find yourself limited when trying to tailor your optimizations and effects for your canvas audience (e.g. mobile devices).

npm install vecmath
...

var Vector3 = require('vecmath').Vector3;

The vecmath API builds on the optimized codebase and structure of Brandon Jones' gl-matrix library, but uses objects and properties for cleaner and more convenient end-user code. Here are some examples of using a Vector3:

//create a new vector, default to (0, 0, 0)
var v = new Vector3();

//set the xyz components
v.set(20, 50, 10);

//or copy the xyz components
v.set(otherVector3);
v.copy(otherVector3); //same as above

//you can chain method calls like so:
var norm = tmpVec.set(enemyPosition).sub(playerPosition).normalize();

It's encouraged to re-use vector objects, instead of allocating new ones inside your render loop.

The vecmath library gives us everything we need to start making 3D animations. This can be done by setting up a projection matrix, and transforming your 3D points into 2D space. However, it gets cumbersome when we want to add traditional camera functionality, like positioning and looking at a target.

This is where cam3d comes in. We can create a 3D perspective camera with its own view and projection matrices like so:

var PerspectiveCamera = require('cam3d').PerspectiveCamera;

//horizontal FOV in radians
var fieldOfView = 75 * Math.PI/180;
var camera = new PerspectiveCamera(fieldOfView, width, height);

Then, when rendering, we project our 3D position into 2D window-space and draw it on screen.

//the 3D world position
var pos = new Vector3(x, y, z); 

//a temporary vector that we can re-use
var out = new Vector3();

... inside render loop ...
//project into 2D space
camera.project(pos, out);

//draw a square particle at that position
context.fillRect(out.x-size/2, out.y-size/2, size, size);