A Place of Ideas

Thoughts on Non-Euclidean Rendering

Related Articles: 4D Rendering

By non-Euclidean geometry, I don't mean portals. I mean a world in which space fundamentally works differently. A world like the one in Hyperbolica, or HyperRogue.

Out of all possible non-Euclidean geometries, two stand out as the simplest. Spherical and hyperbolic. In hyperbolic geometry, there's too much space around you, and it's easy to get lost. In spherical, it's the opposite — there's less space around you. Go too far, and the whole universe closes back in on itself.

Conveniently, the standard graphics pipeline works just as well for these geometries as it does for Euclidean geometry. Let's see how.

Projective Geometry

There's a useful concept called projective geometry. It's geometry without distance or angle. All we have is points, lines, and planes.

Why do we care? Because we can add distance back, after the fact. Depending how we do it, we can get any of the three geometries.

And think about what the graphics pipeline needs. It takes each point in a mesh, connects it to the camera, and takes the intersection with the screen. Then it connects them to make triangles.

None of that needs distance. None of that needs angle. The most it needs is to know what's in front of what.

So it's fair to say that the graphics pipeline doesn't actually use Euclidean geometry. It uses projective geometry.

The Math

The mathematical setup is a bit weird. We represent a point in three-dimensional projective space with four coordinates, one of them being redundant. A point might be written as \([x:y:z:w]\), but that's the same point as \([2x:2y:2z:2w]\).

The projective equivalent of rotations and translations, called a projective transformation, is just represented by any \(4 \times 4\) invertible matrix.

(If you're remembering OpenGL's 4-vectors and 4×4 matrices, that's exactly right.)

Reintroducing Distance

Projective geometry doesn't have a concept of distance or angle. If we add one, we can get back Euclidean geometry, or spherical or hyperbolic, or several others.

A useful way to view this added distance is that it limits which projective transformations are allowed. We only keep the transformations that preserve distance.

Euclidean

When using Euclidean geometry, we typically write points as \((x,y,z)\). We view this as the projective point \([x:y:z:1]\).

The legal transformations are those of the form \(\begin{bmatrix}A&v\\0&1\end{bmatrix}\), where \(A\) is a 3×3 orthogonal matrix, and \(v\) is a vector. This represents rotating by \(A\), then translating by \(v\).

Spherical

When using spherical geometry, we typically write a point as a tuple \((x,y,z,w)\) that satisfies \(x^2+y^2+z^2+w^2 = 1\). (That is, a point on the unit hypersphere.) Of course, we view this as the projective point \([x:y:z:w]\).

The legal transformations are the orthogonal matrices.

Hyperbolic

The legal transformations are the matrices \(A\) satisfying \(\begin{bmatrix}1\\ &1\\ &&1\\ &&&-1\end{bmatrix} A^T \begin{bmatrix}1\\ &1\\ &&1\\ &&&-1\end{bmatrix} = A^{-1}\).

I Need to Write More

There's plenty more to say. But I think this is barely enough information to implement a toy non-Euclidean renderer, and I'm too tired to write more right now. The key is that the OpenGL part is essentially unchanged. You just have to replace the player's position and orientation: instead of the Euclidean \(\begin{bmatrix}A&v\\0&1\end{bmatrix}\), it's one of these other types of transformation.

Examples of what's still needed: