# Multiple subdivision of an icosahedron using HLSL Geometry Shader

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

## Recommended Posts

I've asked this question on stackoverflow.com earlier, but didn't get an answer.
Currently I'm subdividing an icosahedron once by using the following Geometry Shader:

[source lang="cpp"][maxvertexcount(128)]
void gs(triangle VS_OUT gin[3], inout TriangleStream<GS_OUT> s)
{
float3 m0 = .5f * (gin[0].pos_l + gin[1].pos_l),
m1 = .5f * (gin[2].pos_l + gin[1].pos_l),
m2 = .5f * (gin[0].pos_l + gin[2].pos_l);

float3 v[6];
v[0] = gin[0].pos_l;
v[1] = m0;
v[2] = m2;
v[3] = m1;
v[4] = gin[2].pos_l;
v[5] = gin[1].pos_l;

GS_OUT gout;
for (int i = 0; i < 5; ++i)
{
gout.pos_h = mul(float4(v, 1.f), g_mat_wvp);
s.Append(gout);
}
s.RestartStrip();

gout.pos_h = mul(float4(v[1], 1.f), g_mat_wvp);
s.Append(gout);

gout.pos_h = mul(float4(v[5], 1.f), g_mat_wvp);
s.Append(gout);

gout.pos_h = mul(float4(v[3], 1.f), g_mat_wvp);
s.Append(gout);
}[/source]

However, I want to specify the subdivision level. Is there any possibility to call the Shader again with the outputed verticies or do I need to follow an other approach?

##### Share on other sites
There is no way to do it directly in the pipeline without streaming the data out first - either you can use stream output, or possibly output the data in the pixel shader to render targets or a UAV. Then you would re-inject the geometry to the pipeline in the same manner.

Have you considered using the tessellation stages in D3D11? They are made for doing exactly what you are trying to do, and should be able to let you select the tessellation level in a programmatic way.

##### Share on other sites
Have you considered using the tessellation stages in D3D11? They are made for doing exactly what you are trying to do, and should be able to let you select the tessellation level in a programmatic way.

Thanks for your reply. I need to run this in D3D10 as well. So, unfortunately, I cannot use tessellation.

##### Share on other sites
I've solved the problem in the following way:

[source lang="cpp"][maxvertexcount(128)]
void gs(triangle VS_OUT gin[3], inout TriangleStream<GS_OUT> s)
{
if (g_subdivs != 0 && g_subdivs <= MAX_SUBDIVISION_LEVEL)
{
uint level_count = (uint)pow(2, g_subdivs);
float3 u = (gin[1].pos_l - gin[0].pos_l) / level_count,
w = (gin[2].pos_l - gin[0].pos_l) / level_count,
v = gin[0].pos_l;

for (int level = level_count; level > 0; --level)
{
GS_OUT gout;
gout.pos_h = mul(float4(normalize(v), 1.f), g_mat_wvp);
s.Append(gout);

float3 p = v;
uint vertex_count = level + 1;

for (uint vertex = 1; vertex < vertex_count; ++vertex)
{
gout.pos_h = mul(float4(normalize(p + u), 1.f), g_mat_wvp);
s.Append(gout);

gout.pos_h = mul(float4(normalize(p += w), 1.f), g_mat_wvp);
s.Append(gout);
}

v += u;
s.RestartStrip();
}
}
else
{
[unroll]
for (uint i = 0; i < 3; ++i)
{
GS_OUT gout;
gout.diff = gin.diff;
gout.pos_h = mul(float4(gin.pos_l, 1.f), g_mat_wvp);

s.Append(gout);
}
}
}

[/source]

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 18
• 36
• 9
• 16
• 75