Tesselation quad

Started by
2 comments, last by unbird 10 years, 6 months ago

Hi,

I'm learning a tessellation and I have a problem. I try draw a quad with [domain("quad")], but I draw only first triangle.

I have this example from book(I skip some parts like compute tessellation factors depending on distance to the camera and set fixed factors).

Example from book works good, but I can't find mistake in my code.

Here are my Vertices and Indices:


std::vector<Vertex> Vertices;
Vertices.push_back(Vertex(-10.f, +10.f, 0.f));
Vertices.push_back(Vertex(+10.f, +10.f, 0.f));
Vertices.push_back(Vertex(+10.f, -10.f, 0.f));
Vertices.push_back(Vertex(-10.f, -10.f, 0.f));

std::vector<UINT> Indices;
Indices.push_back(0);
Indices.push_back(1);
Indices.push_back(2);
Indices.push_back(3);

And here is my FX:


cbuffer cbPerObject
{
	float4x4 gWorldViewProj;
};
struct VertexIn
{
	float3 PositionL : POSITION;
};
struct VertexOut
{
	float3 PositionL : POSITION;
};
VertexOut VS(VertexIn vin)
{
	VertexOut vout;
	vout.PositionL = vin.PositionL;
	return vout;
}
// Hull Shader Stage
struct PatchTess
{
	float EdgeTessFactor[4] : SV_TessFactor;
	float InsideTessFactor[2] : SV_InsideTessFactor;
};
PatchTess ConstantHS(InputPatch<VertexOut, 4> Patch)
{
	PatchTess pt;
	pt.EdgeTessFactor[0] = 1;
	pt.EdgeTessFactor[1] = 1;
	pt.EdgeTessFactor[2] = 1;
	pt.EdgeTessFactor[3] = 1;
	pt.InsideTessFactor[0] = 1;
	pt.InsideTessFactor[1] = 1;
	return pt;
}
struct HullOut
{
	float3 PositionL : POSITION;
};

[domain("quad")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(4)]
[patchconstantfunc("ConstantHS")]
[maxtessfactor(64.f)]
HullOut HS(InputPatch<VertexOut, 4> Patch, uint i : SV_OutputControlPointID)
{
	HullOut hout;
	hout.PositionL = Patch[i].PositionL;
	return hout;
}
struct DomainOut
{
	float4 PositionH : SV_POSITION;
};
[domain("quad")]
DomainOut DS(PatchTess pt, float2 uv : SV_DomainLocation, const OutputPatch<HullOut, 4> Patch)
{
	float3 v1 = lerp(Patch[0].PositionL, Patch[1].PositionL, uv.x);
	float3 v2 = lerp(Patch[2].PositionL, Patch[3].PositionL, uv.x);
	float3 p = lerp(v1, v2, uv.y);

	DomainOut dout;
	dout.PositionH = mul(float4(p, 1.f), gWorldViewProj);
	return dout;
}
float4 PS(DomainOut pin) : SV_TARGET
{
	return float4(0.f, 1.f, 0.f, 1.f);
}
RasterizerState WireFrameRS
{
	FillMode = WireFrame;
	CullMode = Back;
	FrontCounterClockWise = false;
};
technique11 Tech
{
	pass Normal
	{
		SetVertexShader(CompileShader(vs_5_0, VS()));
		SetHullShader(CompileShader(hs_5_0, HS()));
		SetDomainShader(CompileShader(ds_5_0, DS()));
		SetPixelShader(CompileShader(ps_5_0, PS()));
		SetRasterizerState(WireFrameRS);
	}
}

If I change Indices(to drawing 2 triangles) and domain("quad") for domain("tri") it works good.

Thanks for advice

Advertisement

Recently I attempted to tessellate basic quad as well so I compared your code to mine and my Domain Shader is a bit different:


float3 bilerpUV(float3 v[4], float2 uv) {
	float3 bottom = lerp(v[0], v[1], uv.x);
	float3 top = lerp(v[3], v[2], uv.x); // this line differs
	float3 result = lerp(bottom, top, uv.y);

	return result;
}

DS_OUTPUT main(HS_CONSTANT_DATA_OUTPUT input, const OutputPatch<HS_CONTROL_POINT_OUTPUT, 4> patch, float2 domain : SV_DomainLocation) {
    Output.vPosition = float4(bilerpUV(patch, domain), 1);
    // other code
}

It works thank you(it was probably mistake in the book).

You define your patch corners clockwise, so Zaoshi Kaba's second lerp flipping v[3] and v[2] takes correctly account for that. Otherwise I guess the second triangle got back face culled. Nice shot Zaoshi.

This topic is closed to new replies.

Advertisement