Five canvases draw the same model after each matrix has been applied:
final image, 1 model space, 2 world space (after M), 3 eye space (after V·M),
4 normalized device coordinates (after P·V·M and ÷w). The amber box is the camera’s
view volume. The matrices M, V, P and P·V·M are printed live under the canvases.
Controls: model transform, two camera setups (lookAt, or position + pitch/yaw/roll),
two projections (perspective, parallel), and a toggle that orbits the camera.
Drag and wheel on the small canvases to look around each space.
student.mjs only)createModelMeshes, buildModelParts). Also requires some additions to UI.buildViewLookAtbuildViewEulerbuildPerspectivebuildParallelEach stub returns the identity, so the page runs from the start and each canvas
changes as a step is finished. If a function returns something that is not a finite
4x4 matrix, the page keeps the last good one and prints a warning.
app.html, assets/style.cssmain.mjs controller: DOM, five contexts, frame loopstudent.mjs the exercise;pipeline.mjs composes M, V, P and P·V·M from the stateviews.mjs what each canvas draws; renderer.mjs DOM-free renderer; geometry.mjs meshesstate.mjs state and camera animation; ui.mjs control table and panelmatrixUtil.mjs scale, inverse, matrix formattingshaders/mvp.vert.glsl, shaders/mvp.frag.glsl