Hull Tessellation Concepts

DirectX 11 Computational Graphics Concepts

Tessellation is a technique used in computer graphics to dynamically increase the geometric detail of a mesh. In DirectX 11, this is achieved through a hardware-accelerated tessellation stage integrated into the graphics pipeline. Hull tessellation allows for the generation of finer geometric detail from coarser input primitives (like triangles, quads, or patches) on the GPU, enabling more complex and adaptive surfaces without increasing the complexity of the original model data.

The tessellation process involves three key stages within the DirectX pipeline:

  1. Hull Shader: This shader is responsible for defining the tessellation factors and calculating the tessellated output control points.
  2. Tessellator: The hardware tessellator uses the tessellation factors defined by the hull shader to subdivide the input primitives into smaller primitives (triangles or quads).
  3. Domain Shader: This shader takes the tessellated vertices and the output of the hull shader to calculate the final vertex positions in the tessellated mesh.

Input Primitives and Tessellation Factors

Tessellation in DirectX 11 operates on tessellation patches. These patches can be represented by:

  • Fractional Quad Patches: For tessellating quads.
  • Fractional Triangle Patches: For tessellating triangles.
  • Fractional Line Patches: For tessellating lines.

The tessellation factors determine how much each edge and face of the patch is subdivided. These factors are typically computed by the Hull Shader based on various criteria, such as screen space curvature, distance from the camera, or application-specific logic.

Hull Shader Responsibilities

The Hull Shader plays a crucial role in controlling the tessellation process. It has two main parts:

  • Patch Constant Function: This function runs once per patch and computes the tessellation factors (edge factors and potentially a domain factor). It also sets up the data that will be passed to the Domain Shader for each tessellated vertex.
  • Hull Shader Function: This function runs for each output control point of the patch. It takes the input control points and potentially tessellated domain coordinates to generate the output control points for the tessellated patch.

Example: Tessellation Factor Calculation

The tessellation factors are often clamped to ensure they are within a valid range and can be fractional for adaptive tessellation.

// Inside Hull Shader's Patch Constant Function
float tessFactor[3]; // Edge factors for a triangle
tessFactor[0] = clamp(CalculateEdgeFactor(edge0_control_points), MIN_TESS_FACTOR, MAX_TESS_FACTOR);
tessFactor[1] = clamp(CalculateEdgeFactor(edge1_control_points), MIN_TESS_FACTOR, MAX_TESS_FACTOR);
tessFactor[2] = clamp(CalculateEdgeFactor(edge2_control_points), MIN_TESS_FACTOR, MAX_TESS_FACTOR);
// A domain factor might also be calculated for 3D patches.
SetTessFactors(tessFactor);

Tessellator Stage

The Tessellator stage is a fixed-function hardware unit. It takes the tessellation factors from the hull shader and the input patch vertices. Based on these factors, it generates a grid of tessellated vertices. The tessellator then outputs tessellated primitives (triangles or quads) that are fed into the Domain Shader.

Domain Shader Responsibilities

The Domain Shader runs for each vertex generated by the tessellator. It receives:

  • The interpolated vertex position within the tessellated patch (using barycentric coordinates or similar parameterization).
  • The output control points from the Hull Shader.
  • The tessellation factors.

Using this information, the Domain Shader calculates the final 3D position of each tessellated vertex. This is where complex displacement mapping, procedural geometry generation, and level-of-detail adjustments can be implemented efficiently.

Example: Domain Shader for Displacement Mapping

The Domain Shader can sample a displacement map and offset the vertex based on its position within the patch.

// Inside Domain Shader
// Input: Domain Coordinates (u, v, w), Output Control Points
// Assume displacementMap is sampled using interpolated UVs derived from domain coordinates

float3 displacedVertexPos = lerp(lerp(output_cp0, output_cp1, u), lerp(output_cp2, output_cp3, u), v); // Example for quad
float displacement = displaceMap.Sample(sampler_displace, interpolatedUV).r;

displacedVertexPos.xyz += normal * displacement * displacementScale;

return displacedVertexPos;

Benefits of Hull Tessellation

  • Dynamic Level of Detail (LOD): Automatically generate more polygons where needed (e.g., close to the camera) and fewer where not, optimizing performance.
  • Complex Surface Representation: Create smooth, curved surfaces from low-polygon patches.
  • Displacement Mapping: Achieve realistic surface details by displacing vertices based on texture data.
  • Procedural Geometry: Generate complex geometry on the fly without storing it all in memory.

Note on Tessellation Factors

The tessellation factors dictate the subdivision density. Using very high tessellation factors can significantly increase the vertex count, potentially impacting performance. Careful tuning is required.

Performance Considerations

While powerful, tessellation adds overhead. The hull shader and domain shader must be efficient. Over-tessellation can lead to performance bottlenecks. Always profile your application.