Tesselation Problem

Started by
4 comments, last by bushmanpaul 12 years, 10 months ago
Hi

I recently changed my tesselelation to smooth itself out while using 3 point and now somewhere in the Constant Hull Shader my normal values keep getting mixed up.
I used PNTriangles from the June 2010 SDK as a reference point but I seam to be going nowhere.

The texture co-ordinates and positions seem to be correct becuase if i interpolate them they appear on the correct place and the texture is as it should be but the normals is either facing away from my light source or toward it.

The Constant Hull Shader


CONSTANT_HS_OUTPUT ConstantsHS( InputPatch<VS_INPUT_TESS, 3> ip,uint PatchID : SV_PrimitiveID )
{
CONSTANT_HS_OUTPUT Output = (CONSTANT_HS_OUTPUT)0.0f;

float TessAmount = 1.0f;
if(flags.useTess) TessAmount = 4.0f;

Output.Edges[0] = TessAmount;
Output.Edges[1] = TessAmount;
Output.Edges[2] = TessAmount;

Output.Inside = TessAmount;

// Assign Positions
float3 p003 = ip[0].pos.xyz;
float3 p030 = ip[1].pos.xyz;
float3 p300 = ip[2].pos.xyz;

// Assign Normals
float3 n002 = ip[0].normal.xyz;
float3 n020 = ip[1].normal.xyz;
float3 n200 = ip[2].normal.xyz;

// Edge control points
Output.p210 = ( ( 2.0f * p003 ) + p030 - ( dot( ( p030 - p003 ), n002 ) * n002 ) ) / 3.0f;
Output.p120 = ( ( 2.0f * p030 ) + p003 - ( dot( ( p003 - p030 ), n020 ) * n020 ) ) / 3.0f;
Output.p021 = ( ( 2.0f * p030 ) + p300 - ( dot( ( p300 - p030 ), n020 ) * n020 ) ) / 3.0f;
Output.p012 = ( ( 2.0f * p300 ) + p030 - ( dot( ( p030 - p300 ), n200 ) * n200 ) ) / 3.0f;
Output.p102 = ( ( 2.0f * p300 ) + p003 - ( dot( ( p003 - p300 ), n200 ) * n200 ) ) / 3.0f;
Output.p201 = ( ( 2.0f * p003 ) + p300 - ( dot( ( p300 - p003 ), n002 ) * n002 ) ) / 3.0f;

// Center control point
float3 E = ( Output.p210 + Output.p120 + Output.p021 + Output.p012 + Output.p102 + Output.p201 ) / 6.0f;
float3 V = ( p003 + p030 + p300 ) / 3.0f;
Output.p111 = E + ( ( E - V ) * 0.5f );

// Compute the normals
float V12 = 2.0f * dot( p030 - p003, n002 + n020 ) / dot( p030 - p003, p030 - p003 );
Output.n110 = normalize( n002 + n020 - V12 * ( p030 - p003 ) );

float V23 = 2.0f * dot( p300 - p030, n020 + n200 ) / dot( p300 - p030, p300 - p030 );
Output.n011 = normalize( n020 + n200 - V23 * ( p300 - p030 ) );

float V31 = 2.0f * dot( p003 - p300, n200 + n002 ) / dot( p003 - p300, p003 - p300 );
Output.n101 = normalize( n200 + n002 - V31 * ( p003 - p300 ) );

return Output;
}


Also if I normalize ip[1].normal or ip[2].normal I get an Acces violation error but not if I normalize ip[0].

I attached a picture of a sphere I tried to render with no texture and with diffuse lighting.

Any Ideas?

Any help will be greatly appreciated.Thanks in Advance.
Advertisement
How do things look if you don't do any tessellation? Try forcing your input geometry through the pipeline with tessellation factors manually set to 1.0 and see if you get similar results. If so, perhaps there is something going on with your input geometry.

Are there any warnings or other debug output on the command line?
for me,it looks Sub-D problem,not tessellation itself.
I tested it with no tesselation like Jason Suggested and the tex coord and position are as they should be. but the normals is still messed up.

also I changed my mesh's normals to be that of the accompaning face and then having 3 seperate vertices per face but unfortunately that had little effect and I ended up with a similar messed up sphere.

Also if I normalize any of the input patch values on the second one I get an acces violation so it seems that the first violation is simply ignored. So theres a problem with all my normal inputs but I still can't seem to find it.

My vertex shader simply passes through the values so I don't think theres a problem except the pos for which I add a w value and the normals which I normalize. If i don't normalize the normals then my sphere get messed up even more so the problem probebly lies before the input stage.

The data I use to create my vertex buffer is fine aswel. I simply output the array to a txt file and all was as it should have been.So the problemn lies after that.

Heres the code I used to create my vertex buffer

//create VertexBuffer
D3D11_BUFFER_DESC vBufferDesc;
vBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vBufferDesc.ByteWidth = sizeof(SimpleVert) * numVerts;
vBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vBufferDesc.CPUAccessFlags = 0;
vBufferDesc.MiscFlags = 0;
vBufferDesc.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA initVertexData;
initVertexData.pSysMem = (void*)vertices;
initVertexData.SysMemPitch = 0;
initVertexData.SysMemSlicePitch = 0;

if(FAILED(pDevice->CreateBuffer(&vBufferDesc, &initVertexData, &this->pVertexBuffer)))
{
#ifdef DEBUG_ENABLED
MessageBox(NULL,"Couldn't Create VertexBuffer","Error",0);
#endif
return false;
}


The input layout also look correct


//Creat input Layout
D3D11_INPUT_ELEMENT_DESC elements[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0 , D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT , 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32_FLOAT , 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = _countof( elements );

if(FAILED(pDevice->CreateInputLayout( elements, numElements, pBlobVS->GetBufferPointer(),pBlobVS->GetBufferSize(), &this->pInputLayout )))
{
#ifdef DEBUG_ENABLED
MessageBox(NULL,"Couldn't Create Input Layout","Error",0);
#endif
return false;
};


I am still to go through my code again and see if I can't find something thats not what it should be.

Thanks for you input so far.

I don't get any debug wwarnings or errors.
Isn't your offsets for the vertex elements wrong for the normal vectors? You currently have the offset set to 28, but your tex coord is only 2 32-bit values, so the offset should be set to 20 (at least that is what it looks like to me). Also, should your normal vector have a two component type? According to your shader you are using a three component vector, but the declaration doesn't look like it matches.
Thanks that fixed it. I changed it a while back so that I have a technique class so that I can easily create techniques similair to DX10 and must have accidentally changed some of the values.

Thanks Alot again.

This topic is closed to new replies.

Advertisement