Sign in to follow this  

Subdividing Triangles with the Geometry Shader

This topic is 1873 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I've tried to divide a Triangle into more Triangles and in the end it works but some of the new vertices seems at the wrong position but the computation is correct. Maybe u guys know where's the problem

Just 3 Vertices which perform a Triangle ( full file: https://www.dropbox.com/s/6qzdyid1gcdg7co/GeometryShaderExersise.cpp)

[CODE]
std::vector<Vertex::Geo> v(count);
v[0].Pos = XMFLOAT3(0.0f, 0.0f, 0.0f);
v[0].Normal = XMFLOAT3(1.0f, 1.0f, 1.0f);
v[0].Tex = XMFLOAT2(0.0f, 1.0f);
v[1].Pos = XMFLOAT3(1.0f, 2.0f, 0.0f);
v[1].Normal = XMFLOAT3(1.0f, 1.0f, 1.0f);
v[1].Tex = XMFLOAT2(0.0f, 0.0f);
v[2].Pos = XMFLOAT3(2.0f, 0.0f, 0.0f);
v[2].Normal = XMFLOAT3(1.0f, 1.0f, 1.0f);
v[2].Tex = XMFLOAT2(1.0f, 1.0f);
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex::Geo) * count;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &v[0];
HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &itemVB));
UINT indices[] =
{
0, 1, 2
};
[/CODE]

And here the .FX file ( full file: https://www.dropbox.com/s/tw1sesf55rp60yp/Geometry.fx)

[CODE]
struct VertexIn
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float2 Tex : TEXCOORD;
};
struct VertexOut
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
float2 Tex : TEXCOORD;
};
struct GeoOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW : NORMAL;
float2 Tex : TEXCOORD;
};
Texture2D gDiffuseMap;
VertexOut VS(VertexIn vin)
{
VertexOut vout;
vout = vin;

// Output vertex attributes for interpolation across triangle.
//vout.Tex = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy;
return vout;
}
void Subdivide(VertexOut inVerts[3], out VertexOut outVerts[6])
{
// 1
// *
// / \
// / \
// m0*-----*m1
// / \ / \
// / \ / \
// *-----*-----*
// 0 m2 2
VertexOut m[3];
// compute edge midpoints
m[0].PosL = 0.5f * (inVerts[0].PosL + inVerts[1].PosL);
m[1].PosL = 0.5f * (inVerts[1].PosL + inVerts[2].PosL);
m[2].PosL = 0.5f * (inVerts[2].PosL + inVerts[0].PosL);
// project onto unti spehre
m[0].PosL = normalize(m[0].PosL);
m[1].PosL = normalize(m[1].PosL);
m[2].PosL = normalize(m[2].PosL);
// derive normals
m[0].NormalL = m[0].PosL;
m[1].NormalL = m[1].PosL;
m[2].NormalL = m[2].PosL;
// interpolate texture coordinates
m[0].Tex = 0.5f * (inVerts[0].Tex + inVerts[1].Tex);
m[1].Tex = 0.5f * (inVerts[1].Tex + inVerts[2].Tex);
m[2].Tex = 0.5f * (inVerts[2].Tex + inVerts[0].Tex);
outVerts[0] = inVerts[0];
outVerts[1] = m[0];
outVerts[2] = m[2];
outVerts[3] = m[1];
outVerts[4] = inVerts[2];
outVerts[5] = inVerts[1];
}
void OutputSubdivision(VertexOut v[6], inout TriangleStream<GeoOut> stream)
{
GeoOut gout[6];
[unroll]
for(int i = 0; i < 6; ++i)
{
// Transform to World Space
gout[i].PosW = mul(float4(v[i].PosL, 1.0f), gWorld).xyz;
gout[i].NormalW = mul(v[i].NormalL, (float3x3)gWorldInvTranspose);
// Transform to homogeneous clip space
gout[i].PosH = mul(float4(v[i].PosL, 1.0f), gWorldViewProj);

gout[i].Tex = v[i].Tex;
}
// 1
// *
// / \
// / \
// m0*-----*m1
// / \ / \
// / \ / \
// *-----*-----*
// 0 m2 2
// We can draw the subdivision in two strips:
// strip 1: bottom three triangles
// strip 2: top triangle
[unroll]
for(int j = 0; j < 5; ++j)
{
stream.Append(gout[j]);
}
stream.RestartStrip();
stream.Append(gout[1]);
stream.Append(gout[5]);
stream.Append(gout[3]);
}
[maxvertexcount(8)]
void GS(triangle VertexOut gin[3], inout TriangleStream<GeoOut> stream)
{
VertexOut v[6];
Subdivide(gin, v);
OutputSubdivision(v, stream);
}

float4 PS(GeoOut pin,
[/CODE]

I hope that some one knows whats wrong. I think the calculation is right, but then i dont know why the vertices are positioned that strange

Regards Helgon

Share this post


Link to post
Share on other sites
I've realized that my Vertex Positions just were wrong. Now the triangle is subdivided correctly

[attachment=12542:stupid.jpg]

But if i try to "tesselate" a normal box with the geometry shader it totally crushes the objects geometry.
Independent if its a Box, a GeoSpehre or a Cylinder.

Just as example to see what happens with a box

[attachment=12543:wrong.jpg]

Does someone has an idea whats wrong? It's strange because with a simple triangle it seems to work



Regards Helgon Edited by ~Helgon

Share this post


Link to post
Share on other sites
Just if someone else ever has this problem

In the previous solution i normalized the new vertices after computing them.

Right is it to also normalize the vertices you are calculating with

And it seems that it only works correct for spheres (GeoSpheres not included)

[CODE]
inVerts[0].PosL = normalize(inVerts[0].PosL);
inVerts[1].PosL = normalize(inVerts[1].PosL);
inVerts[2].PosL = normalize(inVerts[2].PosL);
// compute edge midpoints
m[0].PosL = 0.5f * (inVerts[0].PosL + inVerts[1].PosL);
m[1].PosL = 0.5f * (inVerts[1].PosL + inVerts[2].PosL);
m[2].PosL = 0.5f * (inVerts[2].PosL + inVerts[0].PosL);
m[0].PosL = normalize(m[0].PosL);
m[1].PosL = normalize(m[1].PosL);
m[2].PosL = normalize(m[2].PosL);

[/CODE] Edited by ~Helgon

Share this post


Link to post
Share on other sites
Sign in to follow this