JavaScript 3D library where polygons are first class citizens

bower install PolygonJS



JavaScript 3D library where polygons are first class citizens.

Most 3D engines default to implementing a normal vector per vertex. In PolygonJS each face / polygon has a normal. This results in fewer normals and results in a flat-shaded, more geometric look.


PolygonJS uses AMD to organise the JS modules.

PolygonJS uses a right-hand coordinate system.

3D Primer

Coordinate Systems

  • Object Space
  • World Space (Model Space)
  • Camera Space (Eye / View Space)
  • Screen Space (Clip Space)

World Transform Matrix (M)

Places objects within the world.

PolygonJS uses a scene-graph to define the heirarchy of objects in the world.

Childworld = Parentworld * Childlocal

No parent: Childworld = Childlocal

Camera Transform Matrix (C)

Places the camera in the correct position (eye) and orientation in world space.

View Transform Matrix (V)

Matrix transforms vertices from world to view-space. This matrix is the inverse of the camera transform matrix (Identity Matrix = VC, or V = C-1). his is used to transform any object in the scene from world space into view space.

This matrix is usually concatenated together with the object’s world matrix and the projection matrix so that vertices can be transformed from object-space directly to clip-space in the vertex program. [1]
MVP = P * V * M

v' = MVP * v

Projection Transform Matrix (P)

View-space to clip-space (final). Orthographic e.g. isometric or Perspective.

Think of the projection matrix as describing the attributes of your camera, such as field of view, focal length, fish eye lens, etc. Think of the ModelView matrix as where you stand with the camera and the direction you point it. [3]

Relevant OpenGL functions:

Best place to achieve zoom is in the projection transform matrix [3].


Like lights, materials have different ambient, diffuse, and specular colors… In addition to ambient, diffuse, and specular colors, materials have an emissive color, which simulates light originating from an object. In the OpenGL lighting model, the emissive color of a surface adds intensity to the object, but is unaffected by any light sources. Also, the emissive color does not introduce any additional light into the overall scene. [16]


Lights are added as nodes in the scene graph. In addition, diffuse lights have a direction.

Ambient, Diffuse and Specular Lighting.

A good set of settings for a light source would be to set the Diffuse and Specular components to the colour of the light source, and the Ambient to the same colour - but at MUCH reduced intensity, 10% to 40% seems reasonable in most cases... For the glMaterial, it's usual to set the Ambient and Diffuse colours to the natural colour of the object and to put the Specular colour to white. The emission colour is generally black for objects that do not shine by their own light. [17]

Specular Reflection

You can assign a number in the range of [0.0, 128.0] to GL_SHININESS - the higher the value, the smaller and brighter (more focused) the highlight. [17]


  • Pixi.js - used to enable WebGL drawing surface (with 2D Canvas fallback).
  • three.js - awesome 3D library. If I'd discovered this earlier PolygonJS may not exist!


  • Canvas inspector in FF worth exploring [14].


  1. 3D Game Engine Programming - Understanding the View Matrix
  2. Matrix44 - Coordinate Systems (in OpenGL).
  3. Using Viewing and Camera Transforms, and gluLookAt() - OpenGL
  4. Help stamp out GL_PROJECTION abuse - don't combine view and perspective transform matrices! Can screw up z-depth accuracy, lighting (normals), fog calculation etc. etc.
  5. Calculating the gluPerspective matrix and other OpenGL matrix maths
  6. OpenGL Projection Matrix - Song Ho Ahn
  7. c3DL - Canvas 3D JS Library
  8. OpenGL - Transformations
  9. http://www.opengl.org/archives/resources/faq/technical/lookat.cpp
  10. Cameras in OpenGL (ES 2.0)
  11. http://www.songho.ca/opengl/gl_transform.html
  12. http://user.xmission.com/~nate/tutors.html
  13. www.scratchapixel.com - Transforming Points and Vectors
  14. Angelina Fabbro: Improving 2D & 3D Canvas Performance on the Web, One Frame at a Time [JSConf2014] - Use off-screen canvas?
  15. Object properties vs. array - jsPerf test
  16. Lighting & Material
  17. http://sjbaker.org/steve/omniv/opengl_lighting.html