• Create Account

## Subdividing Triangles with the Geometry Shader

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

2 replies to this topic

### #1~Helgon  Members

361
Like
0Likes
Like

Posted 30 November 2012 - 11:16 PM

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)

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
};


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

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,


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

#### Attached Thumbnails

from time to time i find time

### #2~Helgon  Members

361
Like
0Likes
Like

Posted 01 December 2012 - 10:52 AM

I've realized that my Vertex Positions just were wrong. Now the triangle is subdivided correctly

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

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

Regards Helgon

Edited by ~Helgon, 01 December 2012 - 10:52 AM.

from time to time i find time

### #3~Helgon  Members

361
Like
2Likes
Like

Posted 01 December 2012 - 12:30 PM

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)

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);



#### Attached Thumbnails

Edited by ~Helgon, 01 December 2012 - 12:31 PM.

from time to time i find time

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.