## Tessellation Factors

A much more interesting question is what if you apply different tessellation factors to different edges? DirectX11 lets you do this. For a quad there are actually 6 different tessellation factors: one for each edge and two for the centre. The image on the right (taken from Fabien "ryg" Giesen's

*Trip Through the Graphics Pipeline*) shows an example tessellation. The yellow edge factor is 1, green is 2, pink is 3 and cyan is 4. The edge factors determine how many segments to split the original edge into. The horizontal inside factor is 3 and the vertical inside factor is 4; these determine how the inner (white) area is divided. In this case the total quad is split into 3 vertical sections (the leftmost and rightmost being handled by the yellow and pink edge factors) and 4 vertical sections (the top and bottom being the cyan and green edges).

## Proximity-based Tessellation

The inside tessellation factors are calculated as the average of the four edges; I tried a number of different schemes and found this to give the smoothest transitions between tessellation factors, both within a patch and between adjacent patches.

One big problem with non-uniform tessellation is that if two adjacent patches are tessellated with different factors it can introduce holes in the mesh since there are no longer the same number of shared edges along the boundary. One of the benefits of calculating factors on a per-edge basis is that common edges will have the same factor calculated each time, meaning adjacent patches always have the same number of shared edges and the mesh remains contiguous.

## Geometry Shaders

The geometry shader operates on entire primitives (points, lines or triangles, with or without adjacency information) and outputs a stream of such primitives. The interesting thing is that the output stream can be of a different type to the input primitive. For example the input primitive could be a single point and the output stream could be 2 triangles centred on the point to create a quad. This point-sprite expansion algorithm is an effective way of doing particle effects, for instance.

## Proximity-based Wireframe

The two geometry shaders perform similar but mirrored operations. Again both shaders operate on a per-primitive (in this case per-triangle) basis. The first step is to work out whether each vertex is inside or outside the wireframe zone. There are 4 possible cases: all 3 vertices are inside the zone, all 3 vertices are outside the zone, 1 vertex is inside and 2 are outside, 2 vertices are inside and 1 is outside.

**All 3 vertices inside the wireframe zone:**

In this case the geometry shader outputting triangles will output nothing, effectively ignoring that triangle. The shader outputting lines will output 3 lines connecting the vertices together, creating a wireframe representation of that specific triangle.

**All 3 vertices outside the wireframe zone:**

Similarly in this case the shader outputting triangles will output a triangle representing the original input while the shader outputting lines will output nothing, ignoring it.

The interesting cases are when only one or two vertices are inside the wireframe zone. In these cases the original triangle is split into 3 sub-triangles.

**2 vertices inside wireframe zone, 1 outside:**

Since we know which specific vertex is outside the wireframe zone we know which edges of the triangle intersect the zone boundary. By finding the intersection points we can have the triangle-outputting shader output a filled sub-triangle up to the zone boundary and the line-outputting shader output wireframe representations of the remaining two sub-triangles, or vice-versa for

**1 vertex inside wireframe zone, 2 outside**.

Effectively we're splitting the terrain into two distinct meshes: one triangle mesh representing everything outside the wireframe zone and one line mesh representing everything inside the wireframe zone. If we want to we could even offset these meshes to make the distinction even clearer:

## Hairy Terrain

## Zone Control

## Download

*lot*of the keyboard for all the toggles and parameter manipulation. Really need to look into hooking up a GUI library...