Engine notes
Why homography fixes the diagonal kink
Corner pinning is a projective geometry problem. Here is why two ordinary triangles bend the image, and how Projektor keeps a quad perspective-correct.
- Filed
- Read
- 8 minutes
- Note
- 02 / 05
The tempting shortcut: two affine triangles
A quad looks easy to render. Split it along a diagonal, draw two triangles, and interpolate texture coordinates across each one. The GPU is excellent at that job. The catch is that ordinary interpolation inside a triangle is affine, while a projector viewing a tilted plane produces projective perspective.
Each triangle can look plausible on its own, but their rates of change disagree along the shared diagonal. A grid line that should continue smoothly can bend as it crosses that seam. Video makes the error even more obvious because the kink stays fixed while the image moves through it.
Treat the quad as one projective transform
A homography is a 3 by 3 matrix that maps points between two planes in projective space. Four non-degenerate point correspondences are enough to solve it. For corner pinning, those correspondences pair the media rectangle with the four dragged stage corners.
Projektor solves the transform on the CPU when the geometry changes, then gives the result to the WebGL2 shader. During rendering, the shader uses the projective coordinate to recover a texture position for each fragment. The perspective divide is what an affine shortcut lacks.
[x' y' w']ᵀ = H · [u v 1]ᵀ
screenX = x' / w'
screenY = y' / w'
Four media corners + four stage corners → solve HWhy the seam disappears
The quad may still be submitted to the GPU as triangles, because triangles are the rasterizer's native primitive. The important difference is where the texture coordinate comes from. Every fragment is evaluated against the same projective mapping instead of accepting two independent affine stories.
There is no longer a mathematical change of rule at the diagonal. Straight lines on the source remain projectively straight across the whole plane, and moving imagery does not expose a fixed crease through the mapped surface.
- Geometry changes trigger a new matrix solve; ordinary frames reuse that result.
- The fragment shader performs the perspective-aware lookup for the entire quad.
- The result matches the visual model of projecting a flat image onto a flat tilted plane.
Different shapes need different paths
Projektor uses the perspective-correct homography path for quads and ellipses. An ellipse starts from the same projective surface and applies a shape mask. Triangles, polygons, and mesh-warp surfaces use textured mesh paths suited to their geometry.
That distinction matters when choosing a surface. A single tilted rectangular plane is a homography problem. A curved facade, drape, or uneven object cannot be described by one plane, so a mesh with more control points is the more honest model.
Calibrate with the math, not against it
Use a quad when the physical target is planar, even if it looks like a wild trapezoid from the projector's position. Put each corner on the corresponding physical corner and let the projective mapping handle the interior.
If the grid is straight at the edges but bows away from the surface in the middle, adding more corner nudges will not solve the real problem. Switch to mesh warp for curved geometry, or split the target into multiple planar surfaces. The best mapping comes from choosing a model that matches the object.