
iSurfer Part 1: Why Implicit Algebraic Surfaces Demand Per-Pixel GPU Ray Tracing Over Polygon Meshes
Table of Contents (5 sections)▸
When we began designing iSurfer—our undergraduate Computer Engineering thesis at ITBA (Instituto Tecnológico de Buenos Aires), inspired by the IMAGINARY open-mathematics platform and the Oberwolfach Research Institute's SURFER—our goal was to render arbitrary real algebraic surfaces interactively on an iPhone and iPad using OpenGL ES 2.0.
An implicit real algebraic surface is the zero-level set of a trivariate polynomial of degree :
Unlike standard 3D game assets (cars, characters, architecture) modeled as explicit triangle meshes in Blender or Maya, algebraic surfaces are defined purely by mathematical equations:
- Steiner's Roman Surface ():
- Kummer's Quartic (, 16 double points):
- Cayley's Nodal Cubic (, 4 conical nodes):
- The Barth Sextic (, 65 ordinary double points):
The first architectural question every graphics programmer asks is: "Why not just run Marching Cubes on the equation to generate a triangle mesh, upload a Vertex Buffer Object (VBO) to OpenGL ES, and rasterize it normally?"
Here is why polygon meshes fail catastrophically for algebraic geometry—both mathematically and computationally—and why we built a per-pixel GPU ray tracer / raymarcher instead.
1. The Singularity Crisis: Why Marching Cubes Breaks Where #
A point on an algebraic surface is smooth (regular) if the gradient vector does not vanish:
By the Implicit Function Theorem, around any smooth point, the surface behaves locally like a flat plane with a well-defined unit normal .
However, the entire reason mathematicians study surfaces like the Barth Sextic, Chmutov Octic, or Ding-Dong () is their singularities—the points where and simultaneously:
- Ordinary Double Points ( Conical Nodes): Two smooth cones touching tip-to-tip at a single infinitesimal point (65 of them on the Barth Sextic!).
- Cusps & Pinch Points (Whitney Umbrellas): Where a surface sheet folds into a razor-sharp crease or self-intersects along a line.
- Thin Sheets & Grazing Tangents: Where dips to zero and immediately rises back up without changing sign ( everywhere), or changes sign twice inside a microscopic gap.
Click to zoomThe Barth Sextic rendered via per-pixel GPU raymarching — 65 razor-sharp conical double points preserved without mesh tearing
How Voxel Polygonization Fails at Singularities#
Algorithms like Marching Cubes sample on a uniform 3D lattice of cubes with edge length . For each cube, it inspects the 8 corner signs ( or ) and looks up one of pre-triangulated topological cases, placing vertices along cube edges by linear interpolation:
This assumption breaks down in three fundamental ways on algebraic surfaces:
- Sub-Voxel Sign Cancellation: Near a double point where two cone tips meet, the cross-section radius of the cone shrinks to zero. As soon as the cone radius is smaller than the voxel spacing , both sides of the sheet pass between two adjacent grid vertices. Marching Cubes sees the same sign at both corners, concludes the surface does not exist in that cell, and tears a jagged hole right where the cones should touch.
- Manifold Assumption Violation: Marching Cubes is designed to produce a 2-manifold triangle mesh. Algebraic surfaces with self-intersections (like Steiner's Roman Surface, where three planes intersect along the axes) are non-manifold. Marching Cubes forces non-manifold junctions to either separate artificially or fuse into blobby tubes.
- Zero-Gradient Normal Collapse: Even if a vertex lands near a singularity, interpolating vertex normals across a triangle spanning produces wild shading seams and flickering specular highlights.
2. The Memory & Real-Time Edit Wall on Mobile GPUs#
Suppose you try to brute-force Marching Cubes by shrinking the voxel size so the singularities look sharper.
In 3D space, halving multiplies the number of grid cells to evaluate by and the number of output triangles by :
| Grid Resolution | Voxel Evaluations () | Approx. Triangles | Vertex + Normal VBO Size | Time to Re-Mesh on Mobile CPU |
|---|---|---|---|---|
| (Jagged, missing spikes) | ||||
| (Visible faceting) | ||||
| (Unusable for live editing) | ||||
| Out of Memory / Freeze |
In iSurfer, the core user experience is interactive mathematical exploration:
- The user edits a formula or drags a parameter slider to watch a surface morph through a topological transition (for example, watching a smooth cubic surface pinch into Cayley's 4 nodal singularities).
- If every parameter change required re-evaluating grid points on the CPU, running Marching Cubes, allocating megabytes of vertex buffers, and uploading them over the bus via
glBufferData, the frame rate would drop to 0.04 FPS. - Worse, as soon as the user pinches to zoom closely into a singularity, a fixed-resolution mesh reveals ugly flat triangles—requiring a dynamic octree re-meshing pass that stalls the UI thread.
3. The GPU Ray-Tracing Paradigm: Resolution-Independent Implicit Precision#
Instead of discretizing 3D object space into millions of triangles on the CPU, per-pixel GPU ray tracing discretizes only 2D screen space (the pixels currently visible on the display):
- Zero Geometry Buffers: The vertex stage draws only a single bounding volume (a full-screen quad or bounding box/sphere of 2 to 12 triangles). Vertex memory footprint is under 1 KB, regardless of whether the equation is a simple sphere () or a degree-10 Chmutov surface with hundreds of singularities.
- Complexity Scales with Screen Pixels (), Not Volume (): For each pixel covered by the bounding sphere, the fragment shader constructs a viewing ray in object space: Substituting into turns the 3D surface intersection into a 1D univariate equation along the ray:
- Infinite Zoom Without Re-Meshing: When you pinch-zoom into a microscopic conical singularity of the Barth Sextic, the camera ray origin and direction simply narrow their field of view. The fragment shader still solves to floating-point precision for each screen pixel—meaning the singularity remains razor-sharp at any magnification with zero extra memory and zero CPU work!
- Exact Analytical Normals at Every Pixel: Once the smallest positive root is found, the exact hit point is , and the fragment shader evaluates the exact symbolic gradient right at that pixel—eliminating Mach bands and specular wobble completely.
Up Next in Part 2#
Knowing why we must evaluate per pixel inside an OpenGL ES 2.0 fragment shader raises an immediate systems engineering challenge: GLSL shaders are compiled programs on the GPU, not interpreted strings. When a user types a brand-new algebraic equation on the iPhone keyboard, how do we parse it, expand its exponents and derivatives, translate it into optimized GLSL code, and compile it onto the mobile GPU on the fly in milliseconds?