Hardware tessellation as we know it today (Dx11-style) had its origins on the Xbox 360, which released in 2005. Time flies, right? It was a natural step in the evolution toward film-quality realtime rendering. After all, tessellation was a key component of the original Pixar Reyes paper [7].
Now that it’s 20+ years later, we have more experience with the algorithm, and hardware tessellation has not become the solution for these use cases. But the core ideas in Dx11-style tessellation are still good ones, and they’re worth revisiting on their own terms. With the benefit of hindsight, we can take those ideas, make different decisions along the way, and see if we can land on an algorithm that satisfies the same constraints with some more desirable properties.
The final algorithm, once we get there, is going to look like this. It allows us to transition among all the patterns in the header image without popping.
The code is stored as JavaScript, so feel free to use it as you wish (it’s MIT licensed). I essentially took my existing C++ code and said “Mr. Claude, turn this into a JavaScript viewer, GLHF.”
How does Dx11 tessellation work, exactly?
Each edge of a triangle has a tessellation factor that roughly describes how many segments the edge has. In the case of Dx11, this value is in the range [1,64]. The key design decision is that each tess factor is a float value, and we can lerp between any values without a visible pop. From that perspective, we can split tessellation into two subproblems.
Given a tessellation factor, split the edge into line segments. Given those edge line segments, split the interior of the triangle.
There are overviews online [3][4][5], as well as Fabian Giesen’s writeup of the Dx11 tessellator stage [6]. But for this exercise, we’re going to dive into the nitty-gritty details, and derive them as we go.
How should we tessellate a line segment? The most obvious solution would be to use subdivision, splitting each edge in half at each power of two.
Note: Tess factors in Dx11 are from [1,64], but I’ll be using ranges starting at 0 to simplify the formulas.
... continue reading