Skip to content

Canvas (Context3D)

Context3D extends CanvasContext with 3D projection capabilities. It manages view, projection, and combined view-projection matrices, and provides methods to project 3D world-space points onto 2D canvas coordinates. It also exposes a lightDirection vector used by the flat-shading system. Because it inherits from the canvas context, all core drawing state, events, and gradient support are available.

NOTE

For the full API, see the 3D API Reference.

Demo

Creation

ts
import {
    createContext,
} from '@ripl/3d';

const context = createContext('#app');

Or with options:

ts
const context = createContext('#app', {
    fov: 60,
    near: 0.1,
    far: 1000,
});

Properties

  • viewMatrix (Matrix4): the current view (camera) matrix
  • projectionMatrix (Matrix4): the current projection matrix
  • viewProjectionMatrix (Matrix4): combined view × projection matrix
  • lightDirection (Vector3): direction of the light source for shading
  • lightMode ('world' | 'camera'): whether lightDirection is fixed in world space (default) or locked to the viewer like a headlight

Methods

setCamera

Sets the view matrix from eye position, target, and up vector.

ts
context.setCamera([0, 0, 5], [0, 0, 0], [0, 1, 0]);

setPerspective

Updates the perspective projection.

ts
context.setPerspective(fov, near, far);

setOrthographic

Switches to orthographic projection.

ts
context.setOrthographic(left, right, bottom, top, near, far);

project

Projects a 3D point to 2D canvas coordinates.

ts
const [x, y] = context.project([1, 2, 3]);

projectDepth

Returns the projected depth of a 3D point (used for sorting).

ts
const depth = context.projectDepth([1, 2, 3]);

When to Use Canvas

Canvas is the best choice when:

  • Broad browser support: works in all modern browsers without feature detection
  • Simple scenes: sufficient for scenes that don't require hardware depth testing
  • Fallback: use as a fallback for browsers without WebGPU support

What it approximates

The Canvas backend paints flat polygons sorted back to front. It resolves the same lighting model as the WebGPU backend, but where the GPU shades per pixel it can only shade per face — so a few things are approximations rather than differences of degree.

FeatureWebGPUCanvas
Lighting modelIdenticalIdentical, evaluated at the face centroid
Smooth shadingVertex normals interpolated per pixelVertex normals averaged, one colour per face
Per-vertex coloursInterpolated per pixelAveraged, one colour per face
TexturesSampled per pixelAffine per triangle, not perspective-correct
DepthHardware depth bufferBack-to-front sort, so intersecting geometry can flip
Face cullingFragment discardProjected signed area

For a curved primitive at its default segment count, none of these are visible. They show up on large, sparsely subdivided faces — raising the subdivision is the fix in every case.