Basic Triangle Tessellation

August 20, 2011

The next obious step after creating a simple traingle with some text is to figure out how DirectX 11 tessellation works.  Tessellation will likely be handy when I need level of detail with terrain patches.  In this case I’ve started with a simple triangle and 3 control points.  Each control point is a one-to-one match with the 3 verticies of the original triangle.

The C# code is practically identical to the previous post (and the MiniTri example).  There are only three easy changes. The first is to define a wireframe rasterstate:

?View Code CSHARP
RasterizerStateDescription rsd = new RasterizerStateDescription();
            rsd.CullMode = CullMode.Back;
            rsd.FillMode = FillMode.Wireframe;
            rsd.IsMultisampleEnabled = true;
            rsd.IsAntialiasedLineEnabled = true;
            rsd.IsDepthClipEnabled = false;
            rsd.IsScissorEnabled = false;
RasterState_WireFrame = RasterizerState.FromDescription(GraphicsDevice, rsd);

and set the rasterstate just prior to drawing the triangle:

?View Code CSHARP
GraphicsDevice.ImmediateContext.Rasterizer.State = RasterState_WireFrame;

Also don’t forget to set the rasterstate back to null just prior to drawing the text.

The second change is changing the PrimitiveTopology to PatchListWith3ControlPoints.

The third change is to create a new Effect or add an additional technique to an existing effect.fx file. The effect/technique is where all the tessellation happens.

My code is a complete mess at the moment so I’m not going to share it, but I will share my effect file. This effect file is base completed off of Understanding Shader Model 5.0 with DirectX 11. One gotcha is to make sure you set your HullShader and DomainShader to 0 in your any techniques that do not use Hull or Domain shaders (such as your Text technique).

?Download effect.fx
MATRIX g_mViewProjection;
float g_fTessellationFactor = 1;
 
struct VS_CONTROL_POINT_INPUT
{
	float3 vPosition : POSITION;
	float4 vColor : COLOR;
 
}; 
 
struct VS_CONTROL_POINT_OUTPUT
{
	float3 vPosition : POSITION;
	float4 vColor : COLOR;
};
 
struct HS_CONSTANT_DATA_OUTPUT
{
	float Edges[3] : SV_TessFactor;
	float Inside : SV_InsideTessFactor;
};
 
struct HS_OUTPUT
{
	float3 vPosition : POSITION;
	float4 vColor : COLOR;
};
 
VS_CONTROL_POINT_OUTPUT VS( VS_CONTROL_POINT_INPUT input )
{
	VS_CONTROL_POINT_OUTPUT output = (VS_CONTROL_POINT_INPUT)0;
 
	output.vPosition = input.vPosition;
	output.vColor = input.vColor;
 
	return output;
}
 
HS_CONSTANT_DATA_OUTPUT ConstantHS( InputPatch ip, uint PatchID : SV_PrimitiveID )
{
	HS_CONSTANT_DATA_OUTPUT Output;
	Output.Edges[0] = Output.Edges[1] = Output.Edges[2] = g_fTessellationFactor;
	Output.Inside = g_fTessellationFactor;
	return Output;
}
 
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("ConstantHS")]
HS_OUTPUT HS( InputPatch p,
	uint i : SV_OutputControlPointID,
	uint PatchID : SV_PrimitiveID )
{
	HS_OUTPUT Output;
	Output.vPosition = p[i].vPosition;
	Output.vColor = p[i].vColor;
	return Output;
}
 
struct DS_OUTPUT
{
	float4 vPosition : SV_POSITION;
	float4 vColor : COLOR;
};
 
[domain("tri")]
DS_OUTPUT DS( HS_CONSTANT_DATA_OUTPUT input,
	float3 UVW : SV_DomainLocation,
	const OutputPatch quad )
{
	DS_OUTPUT Output;
	float3 finalPos = UVW.x * quad[0].vPosition + UVW.y * quad[1].vPosition + UVW.z * quad[2].vPosition;
	Output.vPosition = float4(finalPos, 1);
	Output.vColor = UVW.x * quad[0].vColor + UVW.y * quad[1].vColor + UVW.z * quad[2].vColor;
	return Output;
}
 
float4 PS( DS_OUTPUT input ) : SV_Target
{
	return input.vColor;
}
 
technique11 TerrainQuad
{
	pass P0
	{
		SetHullShader(		CompileShader( hs_5_0, HS() ) );
		SetDomainShader(	CompileShader( ds_5_0, DS() ) );
		SetVertexShader(	CompileShader( vs_5_0, VS() ) );
		SetPixelShader(		CompileShader( ps_5_0, PS() ) );
	}
}

The tessellation factor is hardcoded in the effect file. Here are some examples of the tessellation:
 

Tessellation = 1


 

Tessellation = 2


 

Tessellation = 16


Tessellation = 64 (apparent maximum)

One Response to “Basic Triangle Tessellation”

  1. Basic tessellation. Starting point for anyone who wanna learn how to create amazing geometry.

    Another thing u should see is Voxels. Its the next Terrain Generation Unit. quite awsm.

    Thanks for the TuT.

Leave a Reply

You must be logged in to post a comment.