projective_js_20090224.jpg

Javascript only supports affine transformations in the Canvas element. In plain English, this means you have control over simple transformations like rotation, scale, and skew. Rendering something with perspective, however, involves a projective transformation and there are no 3D transformation operations within the official Canvas spec to support this sort of thing.

Steven Wittens hacked some code to bypass this limitation and approximate projection transformations. It works by chopping up the source image into several pieces and applying affine transformations to each of the pieces to approximate their projected size and position. If the slices are small enough, it’s barely noticeable.

Perspective views are described by so-called projective transforms, which Canvas2D does not support. However, it does support arbitrary clipping masks as well as affine transforms of both entire and partial images. These can be used to do a fake projective transform: you cut up your textured surface into a bunch of smaller patches (which are almost-affine) and render each with a normal affine transform. Of course you need to place the patches just right, so as to cover any possible gaps. As long as the divisions are small enough, this looks convincingly 3D.

This technique is used in everything from Flash 3D engines to texturing in some PC and console games, but I’m impressed to see it functioning so well in Javascript.

Projective Texturing with Canvas